LynxZh LynxZh - 1 year ago 163
Java Question

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:

@ConfigurationProperties(locations = {"#{myconfigroot.getRootFolder()}/"}
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. (Or may be I write it wrong?) myconfigroot.getRootFolder() is a static method which returns the path to the

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.

I tried once using PropertySourcePlaceHolderConfigurer but seems not work either.

Anybody can share some lights?

Answer Source

Latest Spring boot (version 1.3.5) doesn’t support SpEL in this case.

See JavaDoc of annotation @ConfigurationProperties

Note that contrary to {@code @Value}, SpEL expressions are not evaluated since property values are externalized.

I found a way to customize Spring boot default behavior as follows:

For example, I have file in somewhere, for some reason I cannot get the location before runtime.


Accordingly, define POJO mapping to properties:

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

Then, to extend default StandardEnvironment:

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

Last, apply it in Spring boot main method entry:

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

Once Spring boot starts up, the MyProperties bean name and password fields are injected from Then you could wire the MyProperties bean to other beans as configuration.

Hope it helps!