简体   繁体   English

Spring Boot - 环境@Autowired抛出NullPointerException

[英]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 ,您的JpaConfigPropertyConfig提供的功能已经预先设置@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.

相关问题 Spring Boot @Autowired Environment 抛出 NullPointerException - Spring Boot @Autowired Environment throws NullPointerException Spring Boot Autowired 服务中的 NullPointerException - NullPointerException in Spring Boot Autowired service Spring Hello依赖注入@Autowired抛出NullPointerException - Spring Hello Dependency Injection @Autowired throws NullPointerException Spring Web MVC环境@Autowired仅获取系统属性会引发NullPointerException - Spring Web MVC Environment @Autowired To Get Only System Property throws NullPointerException Spring引导Autowired Service和Repository抛出nullpointerexception - Spring boot Autowired Service and Repository throwing nullpointerexception Spring 在单元测试中启动 @Autowired 返回 NullPointerException - Spring Boot @Autowired in unit test returns NullPointerException Cucumber Java 与 Spring Boot 集成 - Spring @Autowired 抛出 NullPointer 异常 - Cucumber Java with Spring Boot Integration - Spring @Autowired throws NullPointer Exception Spring Boot 自动装配服务 java.lang.NullPointerException - Spring Boot autowired service java.lang.NullPointerException Spring boot JPA CrudRepository 在保存时抛出 NullPointerException - Spring boot JPA CrudRepository throws NullPointerException on save 自动连线的Spring NullPointerException - Autowired Spring NullPointerException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM