当我尝试Autowire时,Environement是空的

时间:2016-02-14 16:44:21

标签: spring properties configuration autowired environment

我正在尝试使用Environment abstraction& @PropertySource of Spring在我的@Configuration注释类中加载和使用属性。但是我在我的PropertyConfig类中将Environment作为null,因为它是从另一个使用它来访问属性的@Configuration类PersistenceConfig访问的。这是我的相关代码:

   @Configuration
  @PropertySource({ "classpath:/properties/email_${environment}.properties" })
  @PropertySource({ "classpath:/properties/appconfig.properties" })
  @PropertySource({ "classpath:/properties/ApplicationResources.properties" })
  @PropertySource({ "classpath:/properties/Database_${environment}.properties" })
  @PropertySource({ "classpath:/properties/log4j.properties" })
  @PropertySource({ "classpath:/properties/system.properties" })
  public class PropertiesConfig {

        @Autowired
        private Environment env;

        private static final PropertiesAccessor propertyAccessor = new                   PropertiesConfig().new PropertiesAccessor();

        public static String getPopertyValue(String property){
            return propertyAccessor.getPropertyValue(property);
        }

        private class PropertiesAccessor{

        public String getPropertyValue(String key){
             return env.getProperty(key);
        }
    }
 }

My Other @Configuration注释类PersistenceConfig如下:

  @Configuration
  @EnableTransactionManagement
  @ComponentScan(basePackages = {"com.template"})
  public class PersistenceConfig {

         @Bean
         public LocalSessionFactoryBean sessionFactory(){

                LocalSessionFactoryBean sessionFactory = new           LocalSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            sessionFactory.setPackagesToScan(new String []                      {"com.template.domain" });
            sessionFactory.setHibernateProperties(hibernateProperties());
            return sessionFactory;


      }

     @Bean
     public BasicDataSource dataSource(){

            BasicDataSource dataSource = new BasicDataSource();
                       dataSource.setDriverClassName(PropertiesConfig.getPopertyValue("jdbc.driverClassName"));
            dataSource.setUrl(PropertiesConfig.getPopertyValue("jdbc.url"));
              dataSource.setUsername(PropertiesConfig.getPopertyValue("jdbc.user"));
                     dataSource.setPassword(PropertiesConfig.getPopertyValue("jdbc.pass"));

            return dataSource;
 }


 @Bean
 public HibernateTransactionManager transactionManager(){
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

Properties hibernateProperties(){
      return new Properties() {
          {
             setProperty("hibernate.hbm2ddl.auto", PropertiesConfig.getPopertyValue("hibernate.hbm2ddl.auto"));
             setProperty("hibernate.dialect", PropertiesConfig.getPopertyValue("hibernate.dialect"));
             setProperty("hibernate.globally_quoted_identifiers", "true");
          }
       };

}

}

但是,当PersistenceConfig的dataSource()方法尝试使用PropertiesConfig.getPopertyValue(" jdbc.driverClassName")检索属性时,我得到NullpointerException,因为PropertyConfig中的类型为Environment的env为null。

我在WebApplicationInitializer中按如下方式加载这两个类:

 public class WebAppInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext container) {
    // Create the 'root' Spring application context
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(PropertiesConfig.class,SecurityConfig.class,PersistenceConfig.class,ApplicationConfig.class);
    //rootContext.register(ApplicationConfig.class, PersistenceConfig.class, SecurityConfig.class); I have not added security yet

    // Manage the life-cycle of the root application context
    container.addListener(new ContextLoaderListener(rootContext));

    // Create the dispatcher servlet's Spring application context
    AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.register(MvcConfig.class);

    // Register and map the dispatcher servlet
    ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");

}

}

据我所知,PersistenceConfig首先在PropertyConfig之前加载。我对吗?或者还有其他原因吗?如何使这项工作?

2 个答案:

答案 0 :(得分:3)

package com.template.config;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration;import     
org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource({ "classpath:/properties/email_${environment}.properties" })
@PropertySource({ "classpath:/properties/appconfig.properties" })
@PropertySource({ "classpath:/properties/ApplicationResources.properties" })
@PropertySource({ "classpath:/properties/Database_${environment}.properties"    

})
@PropertySource({ "classpath:/properties/log4j.properties" })
@PropertySource({ "classpath:/properties/system.properties" })
public class PropertiesConfig {

   @Autowired
   private Environment env;

   private static Environment environment;

   @PostConstruct
   public void init(){
     environment = env;
     System.out.println(environment == env);
   }

   public static String getPopertyValue(String property){
      return environment.getProperty(property);
   }
}

答案 1 :(得分:0)

在方法上使用@PostConstruct来处理你想要的东西。因为你不能在spring init容器之前获取注入bean,所以注入必须在刷新操作之后。 例如:

@Component
public class envConfig {
   @Autowired
   private Environment env;

   //something want to get
   private String[] profiles;

   @PostConstruct                        
   public void init(){
   //get the env properties or throw injected bean to init other bean
   this.profiles=env.getActiveProfiles();
   }
 }