简体   繁体   中英

How to autowire Enviroment into a PropertySourcesPlaceholderConfigurer?

I'm trying to set up my Spring app such that a different .properties files is read depending on the configuration profile. I'm using java config and so what I'm trying to do is this:

@Autowired
private static Environment env;

@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
    PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
    String[] profiles = env.getActiveProfiles();
    String filestring = "environment."+profiles[0]+".properties";
    ClassPathResource properties = new ClassPathResource( filestring );
    Resource[] resources = new ClassPathResource[] { properties };
    pspc.setLocations( resources );
    return pspc;
}

However the env.getActiveProfiles() is giving me a NullPointerException , which I assume means that the environment hasn't been injected. Any one got any ideas how I can fix this? Or alternatively if this is dumb/impossible how I could go about this better?

Just to give you an alternate perspective on your approach (clearly everyone's business case may differ from project to project,) but the type of configuration you are pursuing might lead to other headaches down the road. Security comes to mind. Usually multiple environments means you are dealing with usernames and passwords for various connections to databases and such. Storing those values for a production environment in line with your other configurations could expose sensitive data to developers who need have no knowledge of such things. Rather, if you switch using SPeL expressions and referencing the environment directly, then you can still achieve your runtime configuration but move your settings for each environment to the server (or what-have-you) where those specific configs apply. Example:

<bean id="myDatabase" class="mypackage.MyDatabase" p:username="#{environment['DB_USERNAME']}" p:password="#{environment['DB_PASSWORD']}" .../>

Then on your server, you can pass in system properties OR set environment variables with your desired username and password, and they will be configured at runtime. (The environment expression resolves directly to your Environment instance.)

Just a thought. =)

As @ kungfuters rightly suggested, the business case may differ from application to application. Here is another alternative that worked for my application.

Provide an implementation of following interface:

ApplicationContextInitializer<ConfigurableApplicationContext>

Provide implementation of the following method. The logic to identify the profile goes in this method.

initialize(ConfigurableApplicationContext ctx) 

Based on the identification, set the active profile:

this.applicationContext.getEnvironment().setActiveProfiles(<<yourProfileName>>)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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