Autowired Environment is null Autowired Environment is null java java

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