Autowired Environment is null

后端 未结 4 1615
滥情空心
滥情空心 2020-11-28 08:42

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

@Configuration
@ComponentScan(basePackages = \"my.pack.offer.*\")
@PropertyS         


        
相关标签:
4条回答
  • 2020-11-28 08:58

    Please put this code inside the class where you are trying to autowire the Environment

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    

    It solved my issue. Below I give you my class.

    @Configuration
    @EnableTransactionManagement
    public class DatabaseConfig {   
    /**
     * DataSource definition for database connection. Settings are read from the
     * application.properties file (using the env object).
     */
    @Bean
    public DataSource dataSource() {
    
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("db.driver"));
        dataSource.setUrl(env.getProperty("db.url"));
        dataSource.setUsername(env.getProperty("db.username"));
        dataSource.setPassword(env.getProperty("db.password"));
        return dataSource;
    }
    
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    
      @Autowired
      private Environment env;
    
    }
    
    0 讨论(0)
  • 2020-11-28 09:06

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 09:11

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-28 09:18

    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.

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