2016-02-14 2 views
0

Я пытаюсь использовать абстракцию окружающей среды & @PropertySource Spring для загрузки и использования свойств в аннотированных классах @Configuration. Однако я получаю Environment как null в классе PropertyConfig, поскольку к нему обращаются из другого класса @Configuration PersistenceConfig, который использовал его для доступа к свойствам. Вот мой соответствующий код:Environement is Null при попытке Autowire

@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"); 
      } 
     }; 

} 

}

Однако я получаю NullPointerException когда метод DataSource() из PersistenceConfig пытается получить свойства, используя свойство PropertiesConfig.getPopertyValue ("jdbc.driverClassName"), поскольку env типа Environment имеет значение null в PropertyConfig.

Я загрузки обоих классов следующим образом в моем 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. Я прав? Или есть другая причина? Как это сделать?

+0

Вы ничего не используете ... Вы вызываете статический метод на экземпляр, который вы создали самостоятельно. Весна никогда не будет зависеть от этого. Кроме того, что является дополнительным преимуществом этого, а не напрямую использовать «Среда»? –

+0

Даже несмотря на то, что я обращаюсь к экземпляру среды во внутреннем классе PropertyAccessor, почему Spring не будет авторизовать экземпляр среды в классе PropertiesConfig? Кроме того, это позволяет мне извлекать все свойства с использованием единого метода, а не помещать среду в каждый класс, например PersistenceConfig. –

+0

Извините, я получил то, что вы имеете в виду. –

ответ

0
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); 
    } 
} 
0

использование @PostConstruct на метод обработки, что вы хотите .because вы не можете вводить боб до весны инициализации контейнера, то инъекционные должен быть после операции обновления. например:

@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(); 
    } 
} 
Смежные вопросы