简体   繁体   English

Spring从多个文件中数据多个数据源

[英]Spring data multiple datasources from multiple files

I have 2 (or more) different configuration properties file located in the project and I want to load them for different datasources. 我有两个(或更多)不同的配置属性文件位于项目中,我想为不同的数据源加载它们。

I tried to do as following: 我尝试做如下:

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

But obviously this won't work as the ConfigurationProperties annotation locations property doesn't go through the spEL. 但显然这不起作用,因为ConfigurationProperties注释位置属性不通过spEL。 (Or may be I write it wrong?) myconfigroot.getRootFolder() is a static method which returns the path to the datasource1.properties. (或者我可能写错了?)myconfigroot.getRootFolder()是一个静态方法,它返回datasource1.properties的路径。

Please advice. 请指教。 Thanks. 谢谢。

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

I believe this is a common problem when somebody want their application want to load different configuration files. 我相信当有人希望他们的应用程序想要加载不同的配置文件时,这是一个常见的问题。 Due to some reasons the file location and name can't be put in the startup script or command line, or, the path can only be determined in runtime, that would require spring to load them during the bean creation. 由于某些原因,文件位置和名称不能放在启动脚本或命令行中,或者,路径只能在运行时确定,这需要spring在bean创建期间加载它们。

I tried once using PropertySourcePlaceHolderConfigurer but seems not work either. 我曾尝试使用PropertySourcePlaceHolderConfigurer,但似乎也无法正常工作。

Anybody can share some lights? 有人可以分享一些灯吗?

Latest Spring boot (version 1.3.5) doesn't support SpEL in this case. 在这种情况下,最新的Spring启动(版本1.3.5)不支持SpEL。

See JavaDoc of annotation @ConfigurationProperties 请参阅注释@ConfigurationProperties的 JavaDoc

Note that contrary to {@code @Value}, SpEL expressions are not evaluated since property values are externalized. 请注意,与{@code @Value}相反,由于属性值被外部化,因此不会评估SpEL表达式。

I found a way to customize Spring boot default behavior as follows: 我找到了一种自定义Spring启动默认行为的方法,如下所示:

For example, I have database.properties file in somewhere, for some reason I cannot get the location before runtime. 例如,我在某处有data.properties文件,由于某种原因我无法在运行时之前获取该位置。

username=mike
password=password

Accordingly, define POJO mapping to properties: 因此,定义POJO映射到属性:

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

Then, to extend default StandardEnvironment : 然后,扩展默认的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);
      }
   }
}

Last, apply it in Spring boot main method entry: 最后,将它应用于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);
   }
}

Once Spring boot starts up, the MyProperties bean name and password fields are injected from database.properties. 一旦Spring启动启动, MyProperties bean名称和密码字段将从database.properties中注入。 Then you could wire the MyProperties bean to other beans as configuration. 然后,您可以将MyProperties bean连接到其他bean作为配置。

Hope it helps! 希望能帮助到你!

I finally got it work by using the following mechanism: 我终于通过使用以下机制使其工作:

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);
    }
}

and register the environment post processor into the spring.factories: 并将环境后处理器注册到spring.factories:

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

Anyway, hope this helps people and accept the first anwer as it enlight me. 无论如何,希望这可以帮助人们并接受第一个anwer,因为它让我感到高兴。 Also post the following references from the google search that found during research: 同时发布研究期间发现的谷歌搜索中的以下参考文献:

Where I found how to wire the property source with the environment: https://github.com/spring-projects/spring-boot/issues/4595 我在哪里找到了如何将属性源与环境连接: https//github.com/spring-projects/spring-boot/issues/4595

Where I found how to load the customized properties file: How to configure a custom source to feed Spring Boot's @ConfigurationProperties 我在哪里找到了如何加载自定义属性文件: 如何配置自定义源以提供Spring Boot的@ConfigurationProperties

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM