Nil
Nil

Reputation: 13

creating custom PropertySourcesPlaceholderConfigurer using property loaded dynamically

I am facing some challenge creating PropertySourcesPlaceholderConfigurer based on some value that is available in another property file. I have a property file, custom-{environment}.property, which contains a value, that is needed to set location of PropertySourcesPlaceholderConfigurer.

My CustomConfiguration looks something like:

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
    propertySourcesPlaceholderConfigurer.setLocation(customLocation);
    //Custom url location based on a String available in the properties file. This is the problem area
    return propertySourcesPlaceholderConfigurer;
}

I want to populate this customLocation from the properties file. Tried autowiring Environment, but it's failing as environment is null when placeholderConfigurer() is getting called. Tried using @PropertySource("custom-${environment}.property") and then @Value("**customLocation**"), but that's also not working.

Please let me know how this can be done. Thanks in advance.

Upvotes: 1

Views: 2850

Answers (2)

M. Deinum
M. Deinum

Reputation: 125252

I would suggest adding an ApplicationContextInitializer to load your property files instead of a plain @PropertySource. First load your custom-{environment}.properties next your configurable properties file.

public class PropertySourceInitializer implements ApplicationContextInitializer {

    private static final String DEFAULT_CONFIG_FILE = "classpath:custom-${environment}.properties";

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        final ConfigurableEnvironment env = applicationContext.getEnvironment();
        final MutablePropertySources mps = env.getPropertySources();    
        //
        Resource resource = applicationContext.getResource(env.resolvePlaceholders(DEFAULT_CONFIG_FILE));
        mps.addLast(new ResourcePropertySource(resource.getDescription(), resource));

        String additional = env.getProperty("name.of.property");
        if (StringUtils.hasText(additional) {
            Resource additionalResource = applicationContext.getResource(env.resolvePlaceholders(additional));
            if (additionalResource.isReadable() ) {
                mps.addLast(new ResourcePropertySource(resource.getDescription(), resource));
            }
        }
    }
}

Trying to get it to work with a @PropertySource will be much harder as the phases in which the PropertySourcesPlaceHolderConfigurer is created is different then the one in which the @PropertySource annotations are scanned. Staged loading of @PropertySource (which is basically what you want) is quite difficult. Spring Boot also has its own loading mechanism (which actually is also a ApplicationContextInitializer.

Upvotes: 1

RKodakandla
RKodakandla

Reputation: 3494

Can you try setting your location as a system property?

@Value("#{ systemProperties['myapp.location'] }") 
private String location;

You need to set "myapp.location" as system property.

Upvotes: 0

Related Questions