Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autowired Environment is null

I have an issue with connecting environment to my Spring project. In this class

@Configuration @ComponentScan(basePackages = "my.pack.offer.*") @PropertySource("classpath:OfferService.properties") public class PropertiesUtil {     @Autowired     private Environment environment;        @Bean     public String load(String propertyName)     {         return environment.getRequiredProperty(propertyName);     } } 

environment always is null.

like image 767
LeYar Avatar asked Oct 17 '13 07:10

LeYar


People also ask

Why Autowired is giving null?

The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.

Why is @autowired not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

Why is my Spring bean null?

Using the HelloWorldService below as a bean in a Spring application would fail. As there is no @Autowired (or @Inject or @Resource ) on the field, Spring doesn't know it needs to inject a dependency into the field. So the field remains null .

Can a bean be null?

Internal representation of a null bean instance, e.g. for a null value returned from FactoryBean. getObject() or from a factory method. Each such null bean is represented by a dedicated NullBean instance which are not equal to each other, uniquely differentiating each bean as returned from all variants of BeanFactory.


2 Answers

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);     } } 
like image 200
Alex Shesterov Avatar answered Oct 02 '22 14:10

Alex Shesterov


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.

like image 31
Josue Montano Avatar answered Oct 02 '22 13:10

Josue Montano