Spring Boot - Environment @Autowired throws NullPointerException

前端 未结 4 1174
攒了一身酷
攒了一身酷 2020-11-30 07:46

I have a project setup using Spring Boot 0.5.0.M5.

In one of the configuration files I am trying to @Autowire Environment but that fail

相关标签:
4条回答
  • 2020-11-30 08:22

    I was having the similar issue to read properties from my application.properties file in spring boot application. I have struggled a lot to figure out the problem and make it work. Finally I have done. Here is my Constants class which will read properties values from properties file. I hope it will help to someone.

    import org.springframework.context.EnvironmentAware;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
    import org.springframework.core.env.Environment;
    
    @Configuration
    @PropertySource("classpath:application.properties")
    public class Constants implements EnvironmentAware {
    
    static Environment environment;
    
    @Override
    public void setEnvironment(Environment environment) {
        Constants.environment = environment;
    }
    
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    
    public static String getActiveMQHost() {
        System.out.println(environment.getProperty("spring.activemq.broker-host"));
        return environment.getProperty("spring.activemq.broker-host");
    }
    
    public static String getActiveMQPort() {
        System.out.println(environment.getProperty("spring.activemq.broker-port"));
        return environment.getProperty("spring.activemq.broker-port");
    }
    
    public static String getActiveMQUser() {
        System.out.println(environment.getProperty("spring.activemq.user"));
        return environment.getProperty("spring.activemq.user");
    }
    
    public static String getActiveMQPassword() {
        System.out.println(environment.getProperty("spring.activemq.password"));
        return environment.getProperty("spring.activemq.password");
    }
    
    }
    

    These are the property key's declared in my application.properties,

    spring.activemq.broker-host
    spring.activemq.broker-port
    spring.activemq.user
    spring.activemq.password
    
    0 讨论(0)
  • 2020-11-30 08:25

    I had the same problem on Spring Batch. Writers cannot autowire Environment class because Configuration class was instantiated earlier. So I created a sort of Singleton (old manner) to instantiate Environment and I could access to it every time.

    I did this implementation :

    @Configuration
    @PropertySource(value = { "classpath:kid-batch.properties" }, ignoreResourceNotFound = false)
    public class BatchConfiguration implements EnvironmentAware {
    
    private static Environment env;
    
    public static String getProperty(String key) {
        return env.getProperty(key);
    }
    
    @Override
    public void setEnvironment(Environment env) {
        BatchConfiguration.env = env;
    }
    

    }

    And it works

    0 讨论(0)
  • 2020-11-30 08:26

    Though your specific problem is solved, here's how to get Environment in case Spring's autowiring happens too late.

    The trick is to implement org.springframework.context.EnvironmentAware; Spring then passes environment to setEnvironment() method. This works since Spring 3.1.

    An example:

    @Configuration
    @PropertySource("classpath:myProperties.properties")
    public class MyConfiguration implements EnvironmentAware {
    
        private Environment environment;
    
        @Override
        public void setEnvironment(final Environment environment) {
            this.environment = environment;
        }
    
        public void myMethod() {
            final String myPropertyValue = environment.getProperty("myProperty");
            // ...
        }
    
    }
    

    This is not as elegant as @Autowired or @Value, but it works as workaround in some situations.

    0 讨论(0)
  • 2020-11-30 08:36

    I believe there were some lifecycle issues with Spring and the EntityManagerFactory, and you might have fallen foul of those (fixed in 4.0.0.RC1) - if your @Configuration class gets instantiated super early, it might not be eligible for autowiring. You can probably tell from the log output if that is the case.

    Just out of interest, did you know that the functionality provided by your JpaConfig and PropertyConfig is already presetn out of the box if you use @EnableAutoConfiguration (as long as you @ComponentScan that package where your repositories are defined)? See the JPA sample in Spring Boot for an example.

    0 讨论(0)
提交回复
热议问题