[英]Spring Boot - Environment @Autowired throws NullPointerException
I have a project setup using Spring Boot 0.5.0.M5 . 我使用Spring Boot 0.5.0.M5进行项目设置。
In one of the configuration files I am trying to @Autowire Environment
but that fails with a NullPointerException
. 在其中一个配置文件中,我正在尝试使用
@Autowire Environment
但是因为NullPointerException
而失败。
Here's what I have so far: 这是我到目前为止所拥有的:
Application.java Application.java
@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
JpaConfig.java where I am trying to @Autowire Environment
JpaConfig.java我正在尝试
@Autowire Environment
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.ui.persistence.repository")
public class JpaConfig {
private static final String DATABASE_DRIVER = "db.driver";
private static final String DATABASE_PASSWORD = "db.password";
private static final String DATABASE_URL = "db.url";
private static final String DATABASE_USERNAME = "db.username";
private static final String HIBERNATE_DIALECT = "hibernate.dialect";
private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String ENTITYMANAGER_PACKAGES_TO_SCAN
= "entitymanager.packages.to.scan";
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty(DATABASE_DRIVER));
dataSource.setUrl(env.getProperty(DATABASE_URL));
dataSource.setUsername(env.getProperty(DATABASE_USERNAME));
dataSource.setPassword(env.getProperty(DATABASE_PASSWORD));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean
= new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(
HibernatePersistence.class);
entityManagerFactoryBean.setPackagesToScan(
env.getProperty(ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(hibernateProperties());
return entityManagerFactoryBean;
}
}
I am trying to load the database properties configured in a properties file. 我正在尝试加载属性文件中配置的数据库属性。 However, the
Environment
is not injected and the code fails with NullPointerException
. 但是,未注入
Environment
,并且代码因NullPointerException
而失败。 I do not have any configuration in XML files. 我在XML文件中没有任何配置。
For the properties file I have configured PropertySourcesPlaceholderConfigurer
this way: 对于属性文件,我已经以这种方式配置了
PropertySourcesPlaceholderConfigurer
:
@Configuration
@PropertySource("classpath:database.properties")
public class PropertyConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
I have tried swapping @Autowired
, @Resource
and @Inject
but nothing has worked so far. 我尝试过交换@
@Autowired
, @Resource
和@Inject
但到目前为止还没有任何工作。 Would appreciate any help. 非常感谢任何帮助。 Thanks.
谢谢。
Though your specific problem is solved, here's how to get Environment
in case Spring's autowiring happens too late . 虽然您的具体问题已经解决,但是如果Spring的自动装配发生得太晚 , 这里是如何获得
Environment
的 。
The trick is to implement org.springframework.context.EnvironmentAware
; 诀窍是实现
org.springframework.context.EnvironmentAware
; Spring then passes environment to setEnvironment()
method. Spring然后将环境传递给
setEnvironment()
方法。 This works since Spring 3.1. 这适用于Spring 3.1。
An example: 一个例子:
@Configuration
@PropertySource("classpath:myProperties.properties")
public class MyConfiguration implements EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(final Environment environment) {
this.environment = environment;
}
public void myMethod() {
final String myPropertyValue = environment.getProperty("myProperty");
// ...
}
}
This is not as elegant as @Autowired
or @Value
, but it works as workaround in some situations. 这不像
@Autowired
或@Value
那样优雅,但在某些情况下它可以解决方法。
I believe there were some lifecycle issues with Spring and the EntityManagerFactory
, and you might have fallen foul of those (fixed in 4.0.0.RC1) - if your @Configuration
class gets instantiated super early, it might not be eligible for autowiring. 我相信Spring和
EntityManagerFactory
存在一些生命周期问题,你可能已经违反了那些(在4.0.0.RC1中修复) - 如果你的@Configuration
类超级实例化,它可能没有资格进行自动装配。 You can probably tell from the log output if that is the case. 您可以从日志输出中判断出是否是这种情况。
Just out of interest, did you know that the functionality provided by your JpaConfig
and PropertyConfig
is already presetn out of the box if you use @EnableAutoConfiguration
(as long as you @ComponentScan
that package where your repositories are defined)? 只是出于兴趣,您是否知道如果您使用
@EnableAutoConfiguration
,您的JpaConfig
和PropertyConfig
提供的功能已经预先设置@EnableAutoConfiguration
(只要您@ComponentScan
定义了您的存储库的包)? See the JPA sample in Spring Boot for an example. 有关示例,请参阅Spring Boot中的JPA示例 。
I had the same problem on Spring Batch. 我在Spring Batch上遇到了同样的问题。 Writers cannot autowire Environment class because Configuration class was instantiated earlier.
编写者无法自动装配Environment类,因为之前已实例化Configuration类。 So I created a sort of Singleton (old manner) to instantiate Environment and I could access to it every time.
所以我创建了一种Singleton(旧方式)来实例化Environment,我每次都可以访问它。
I did this implementation : 我做了这个实现:
@Configuration
@PropertySource(value = { "classpath:kid-batch.properties" }, ignoreResourceNotFound = false)
public class BatchConfiguration implements EnvironmentAware {
private static Environment env;
public static String getProperty(String key) {
return env.getProperty(key);
}
@Override
public void setEnvironment(Environment env) {
BatchConfiguration.env = env;
}
} }
And it works 它有效
I was having the similar issue to read properties from my application.properties file in spring boot application. 我有类似的问题从spring boot应用程序中的application.properties文件中读取属性。 I have struggled a lot to figure out the problem and make it work.
我经常努力找出问题并使其发挥作用。 Finally I have done.
最后我做了。 Here is my Constants class which will read properties values from properties file.
这是我的Constants类,它将从属性文件中读取属性值。 I hope it will help to someone.
我希望它对某人有所帮助。
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource("classpath:application.properties")
public class Constants implements EnvironmentAware {
static Environment environment;
@Override
public void setEnvironment(Environment environment) {
Constants.environment = environment;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
public static String getActiveMQHost() {
System.out.println(environment.getProperty("spring.activemq.broker-host"));
return environment.getProperty("spring.activemq.broker-host");
}
public static String getActiveMQPort() {
System.out.println(environment.getProperty("spring.activemq.broker-port"));
return environment.getProperty("spring.activemq.broker-port");
}
public static String getActiveMQUser() {
System.out.println(environment.getProperty("spring.activemq.user"));
return environment.getProperty("spring.activemq.user");
}
public static String getActiveMQPassword() {
System.out.println(environment.getProperty("spring.activemq.password"));
return environment.getProperty("spring.activemq.password");
}
}
These are the property key's declared in my application.properties, 这些是我的application.properties中声明的属性键,
spring.activemq.broker-host
spring.activemq.broker-port
spring.activemq.user
spring.activemq.password
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.