我正在尝试使用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之前加载。我对吗?或者还有其他原因吗?如何使这项工作?
答案 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();
}
}