【问题标题】:Spring : Add properties file externallySpring:在外部添加属性文件
【发布时间】:2018-06-22 07:47:14
【问题描述】:

我正在开发一个 Spring-MVC 应用程序,我们正准备在不同的服务器上设置应用程序。由于每个服务器都可以有自己的数据库相关配置,我们希望使用一个可以在项目启动时读取的外部属性文件(war 文件之外)。我该如何处理这种方法? 为了让它工作,我已经将应用程序初始化代码移到了 Java 中,这样就不需要我们之前的静态 XML 读取了。 但是,我们不确定如何动态创建和添加至少具有这 3 个值(包含 DB 名称、用户名、密码的 JDBC URL)的属性文件。所有表,其他数据将自动创建。

这是初始化应用程序的类:

WebConfig.java:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.ourapp.spring"})
@EnableTransactionManagement
@EnableCaching
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    @Bean
    public ReloadableResourceBundleMessageSource messageSource(){
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("../resources/locale/messages.properties");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocaleChangeInterceptor localeInterceptor(){
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        return interceptor;
    }

    @Bean
    public MappingJackson2HttpMessageConverter converter() {
        return new MappingJackson2HttpMessageConverter();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/img/**").addResourceLocations("/img/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    }

    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("../webapp/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public DoNotTruncateMyUrls doNotTruncate(){
       return new DoNotTruncateMyUrls();
    }

    @Bean
    public MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Bean
    @Qualifier("primary_tx")
    public HibernateTransactionManager getPrimaryTransactionManager() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(sessionFactory().getObject());
        return txName;
    }

    @Bean
    @Qualifier("extended_tx")
    public HibernateTransactionManager txName() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(getExtendedSessionFactory().getObject());
        return txName;
    }

    @Bean
    @Qualifier("sessionFactory_origin")
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(new DataSourceConfig().primaryDataSource());
        sessionFactory.setPackagesToScan("com.ourapp.spring");
        return sessionFactory;
    }

    @Bean
    @Qualifier("sessionFactory_extended")
    public LocalSessionFactoryBean getExtendedSessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(new DataSourceConfig_Extended().secondaryDataSource());
        sessionFactory.setPackagesToScan("com.ourapp.spring");
        return sessionFactory;
    }

}

谢谢。 :-)

【问题讨论】:

  • 你在用弹簧靴吗?如果是这样,您可以使用配置服务器
  • @pvpkiran :不,不幸的是我使用的是 spring-mvc。

标签: java spring spring-mvc migration


【解决方案1】:

您可能正在寻找的是 Profiles(@Profile or @Conditional)

第 1 步:创建个人资料。以下是产品配置文件的示例。同样,您可以为devqa 创建一个

import javax.activation.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jndi.JndiObjectFactoryBean;

@Configuration
@Profile("prod")
@PropertySource("classpath:/com/<SomePath>/app.properties")
public class ProductionProfileConfig {

    @Autowired Environment env;

    @Bean
    public DataSource dataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName(env.getProperty("dbName"));
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) jndiObjectFactoryBean.getObject();
    }
}

第 2 步激活配置文件

Spring 在确定哪些配置文件时遵循两个独立的属性 处于活动状态:spring.profiles.activespring.profiles.default。如果 spring.profiles.active 被设置,那么它的值决定了哪个 配置文件处于活动状态。但是如果 spring .profiles.active 没有设置,那么 Spring 看起来是 spring.profiles.default。如果两者都没有 spring.profiles.active 也没有 spring.profiles.default 设置,然后有 没有活动配置文件,只有那些未定义为的 bean 在配置文件中创建

更新

如果文件位于打包的战争之外,请使用PropertyConfigurator.configure(Loader.getResource(&lt;your-file-path&gt;));。稍后您可以使用 @Value or SPel 简单地注入值

【讨论】:

  • 此文件将位于何处?特别是在码头上,这是一个问题,因为码头在一些随机命名的文件夹中的 /tmp 中解压战争。
  • 这就是你把它放在类路径上的方式。如果文件在 src 文件夹中,直接使用 /file.properties
  • 我希望将它放在 WAR 文件之外。任何方式我都可以通过将其放置在外部某处来做到这一点
  • 使用 PropertyConfigurator.configure(Loader.getResource());稍后您可以简单地使用 @Value 或 SPel 注入值
【解决方案2】:

编写一个配置管理器,它将根据属性文件的名称创建配置对象。例如,

Configuration config = ConfigurationManager.getConfig("dbConfig");

所以,现在您的配置对象将包含与 db.xml 相关的所有属性。当您实例化配置对象时,将所有属性读入该对象。

假设您的属性文件包含以下字段:

user.name = "Tom" user.password = "pass"

下次需要“user.name”时,只需config.getString("user.name")

【讨论】:

  • 此 db.config 将位于何处?
  • 更好的方法是创建一个单独的 Web 服务,只为您的属性提供服务
  • 即使创建了新服务,我也必须在启动期间加载数据库值。单独的网络服务将如何改变它
【解决方案3】:

您可以使用PropertySourcesPlaceholderConfigurer 来做到这一点

像这样创建一个 bean

@Bean
public static PropertySourcesPlaceholderConfigurer devPropertyPlaceholderConfigurer() throws IOException {
   PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
   configurer.setLocations(new PathMatchingResourcePatternResolver().getResources("file:pathtToFile"));
   configurer.setIgnoreUnresolvablePlaceholders(true);
   return configurer;
}

例如,如果您编写 file:/tmp/dev/*.properties 。它将加载 /tmp/dev 下的所有属性文件。

如果您想根据不同的环境(开发、测试、生产)对其进行自定义。那么你可以使用@Profile 并创建多个bean。

@Bean
@Profile("dev")
public static PropertySourcesPlaceholderConfigurer devPropertyPlaceholderConfigurer() throws IOException {
   ..... // give dev properties file path
}


@Bean
@Profile("testing")
public static PropertySourcesPlaceholderConfigurer testPropertyPlaceholderConfigurer() throws IOException {
.....// give test properties file path
}

@Bean
@Profile("prod")
public static PropertySourcesPlaceholderConfigurer prodPropertyPlaceholderConfigurer() throws IOException {
.....// give prod properties file path
}

【讨论】:

    猜你喜欢
    • 2015-05-14
    • 2019-05-15
    • 2020-07-30
    • 2016-06-18
    • 2012-08-01
    • 2018-02-21
    • 2015-06-26
    • 1970-01-01
    相关资源
    最近更新 更多