我在将环境连接到Spring项目时遇到问题。 在这堂课
@Configuration
@ComponentScan(basePackages = "my.pack.offer.*")
@PropertySource("classpath:OfferService.properties")
public class PropertiesUtil {
@Autowired
private Environment environment;
@Bean
public String load(String propertyName)
{
return environment.getRequiredProperty(propertyName);
}
}
环境始终为null。
答案 0 :(得分:30)
自动装配发生的时间晚于调用load()
(出于某种原因)。
解决方法是实现EnvironmentAware
并依赖Spring调用setEnvironment()
方法:
@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);
}
}
答案 1 :(得分:14)
为 @Autowired
(来自javax.annotation)更改@Resource
并将其设为public
,例如:
@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;
}
}
您必须以这种方式在WebApplicationInitializer中注册您的configurer类
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ApplicationConfigurer.class); //ApplicationConfigurer imports HibernateConfigurer
这对我有用!您可以查看a test project I made。
答案 2 :(得分:0)
我用构造函数注入解决了同样的问题:
@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"))
}
}
后来,我将其简化为这种形式(以使属性正确注入):
@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
}
}
答案 3 :(得分:-1)
请将此代码放在您尝试自动装配环境的类中
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
它解决了我的问题。下面我给你上课。
@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;
}