Spring从多个文件

时间:2016-06-14 08:25:00

标签: java spring spring-boot spring-data-jpa

我在项目中有两个(或更多)不同的配置属性文件,我想为不同的数据源加载它们。

我试着做如下:

@Bean
@ConfigurationProperties(locations = {"#{myconfigroot.getRootFolder()}/datasource1.properties"}
public static DataSource getFirstDatasource() {
    return DataSourceBuilder.create().build();
}

但显然这不会起作用,因为ConfigurationProperties注释位置属性没有通过spEL。 (或者我可能写错了?)myconfigroot.getRootFolder()是一个静态方法,它返回datasource1.properties的路径。

请指教。感谢。

=====已编辑=======

我相信当有人希望他们的应用程序想要加载不同的配置文件时,这是一个常见的问题。由于某些原因,文件位置和名称不能放在启动脚本或命令行中,或者,路径只能在运行时确定,这需要spring在bean创建期间加载它们。

我曾尝试使用PropertySourcePlaceHolderConfigurer,但似乎也无法正常工作。

有人可以分享一些灯吗?

2 个答案:

答案 0 :(得分:2)

最新的Spring启动(版本1.3.5)在这种情况下不支持SpEL。

请参阅注释 @ConfigurationProperties

的JavaDoc
  

请注意,与{@code @Value}相反,SpEL表达式不是   评估,因为属性值被外部化。

我找到了一种自定义Spring启动默认行为的方法,如下所示:

例如,我在某处有 database.properties 文件,由于某种原因我无法在运行时获取该位置。

username=mike
password=password

因此,定义POJO映射到属性:

@Component
@ConfigurationProperties(locations = "myConfiguration")// myConfiguration is customized placeholder
public class MyProperties{
   String username;
   String password;
   //Getters, Setters…
}

然后,扩展默认StandardEnvironment

public class MyEnvironment extends StandardEnvironment {
   @Override
   public String resolvePlaceholders(String location) {
      if (location.equals("myConfiguration")) {
         //Whatever you can do, SpEL, method call...
         //Return database.properties path at runtime in this case
         return getRootFolder() + "datasource.properties"; 
      } else {
         return super.resolvePlaceholders(text);
      }
   }
}

最后,将它应用于Spring boot main方法条目:

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
    new SpeedRestApplication()
        .configure(new SpringApplicationBuilder(SpeedRestApplication.class).environment(new MyEnvironment()))//Replace default StandardEnvironment
        .run(args);
   }
}

Spring启动后, MyProperties bean名称和密码字段将从database.properties中注入。然后,您可以将 MyProperties bean连接到其他bean作为配置。

希望它有所帮助!

答案 1 :(得分:1)

我终于通过使用以下机制来实现它:

public class DatasourcePostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Properties p = new Properties();
        p.load(new FileInputStream(new File(getRootFolder() + "/datasource1.properties")));
        Map<String, Object> propMap = new HashMap<>();
        for (Map.Entry<Object, Object> entry : p.entrySet()) {
            propMap.put(entry.getKey().toString(), entry.getValue());
        }
        MapPropertySource source = new MapPropertySource("datasource1", propMap);
        environment.getPropertySources().addLast(source);
    }
}

并将环境后处理器注册到spring.factories:

 org.springframework.boot.env.EnvironmentPostProcessor=com.myorg.test.DatasourcePostProcessor

无论如何,希望这可以帮助人们并接受第一个安慰,因为它让我感到高兴。同时发布研究期间发现的谷歌搜索中的以下参考文献:

我在哪里找到了如何将属性源与环境相连接:https://github.com/spring-projects/spring-boot/issues/4595

我在哪里找到了如何加载自定义属性文件:How to configure a custom source to feed Spring Boot's @ConfigurationProperties