Autowired Environment is null
Autowiring happens later than load()
is called (for some reason).
A workaround is to implement EnvironmentAware
and rely on Spring calling setEnvironment()
method:
@Configuration@ComponentScan(basePackages = "my.pack.offer.*")@PropertySource("classpath:OfferService.properties")public class PropertiesUtil implements EnvironmentAware { private Environment environment; @Override public void setEnvironment(final Environment environment) { this.environment = environment; } @Bean public String load(String propertyName) { return environment.getRequiredProperty(propertyName); }}
Change @Autowired
for @Resource
(from javax.annotation) and make it public
e.g.:
@Configuration@PropertySource("classpath:database.properties")public class HibernateConfigurer { @Resource public Environment env; @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty("database.driverClassName")); dataSource.setUrl(env.getProperty("database.url")); dataSource.setUsername(env.getProperty("database.username")); dataSource.setPassword(env.getProperty("database.password")); dataSource.setValidationQuery(env.getProperty("database.validationQuery")); return dataSource; }}
And you must register your configurer class in WebApplicationInitializer this way
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(ApplicationConfigurer.class); //ApplicationConfigurer imports HibernateConfigurer
It's working for me! You may want to check a test project I made.
I solved the same problem with constructor injection:
@Configuration@PropertySource("classpath:my.properties")public class MyConfig { private Environment environment; public MyConfig(Environment environment) { this.environment = environment } @Bean public MyBean myBean() { return new MyBean(environment.getRequiredProperty("srv.name")) }}
later, I simplified it to this form (to make properties injected properly):
@Configuration@PropertySource("classpath:my.properties")public class MyConfig { private String serviceName; public MyConfig(Environment ignored) { /* No-op */ } @Value("${srv.name}") public void setServiceName(String serviceName) { this.serviceName = serviceName; } @Bean public MyBean myBean() { return new MyBean(requireNonNull(serviceName)); // NPE without environment in constructor }}