繁体   English   中英

Spring Boot - 环境@Autowired抛出NullPointerException

[英]Spring Boot - Environment @Autowired throws NullPointerException

我使用Spring Boot 0.5.0.M5进行项目设置。

在其中一个配置文件中,我正在尝试使用@Autowire Environment但是因为NullPointerException而失败。

这是我到目前为止所拥有的:

Application.java

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

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

我正在尝试加载属性文件中配置的数据库属性。 但是,未注入Environment ,并且代码因NullPointerException而失败。 我在XML文件中没有任何配置。

对于属性文件,我已经以这种方式配置了PropertySourcesPlaceholderConfigurer

@Configuration
@PropertySource("classpath:database.properties")
public class PropertyConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

我尝试过交换@ @Autowired@Resource@Inject但到目前为止还没有任何工作。 非常感谢任何帮助。 谢谢。

虽然您的具体问题已经解决,但是如果Spring的自动装配发生得太晚这里是如何获得Environment

诀窍是实现org.springframework.context.EnvironmentAware ; Spring然后将环境传递给setEnvironment()方法。 这适用于Spring 3.1。

一个例子:

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

}

这不像@Autowired@Value那样优雅,但在某些情况下它可以解决方法。

我相信Spring和EntityManagerFactory存在一些生命周期问题,你可能已经违反了那些(在4.0.0.RC1中修复) - 如果你的@Configuration类超级实例化,它可能没有资格进行自动装配。 您可以从日志输出中判断出是否是这种情况。

只是出于兴趣,您是否知道如果您使用@EnableAutoConfiguration ,您的JpaConfigPropertyConfig提供的功能已经预先设置@EnableAutoConfiguration (只要您@ComponentScan定义了您的存储库的包)? 有关示例,请参阅Spring Boot中JPA示例

我在Spring Batch上遇到了同样的问题。 编写者无法自动装配Environment类,因为之前已实例化Configuration类。 所以我创建了一种Singleton(旧方式)来实例化Environment,我每次都可以访问它。

我做了这个实现:

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

}

它有效

我有类似的问题从spring boot应用程序中的application.properties文件中读取属性。 我经常努力找出问题并使其发挥作用。 最后我做了。 这是我的Constants类,它将从属性文件中读取属性值。 我希望它对某人有所帮助。

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

}

这些是我的application.properties中声明的属性键,

spring.activemq.broker-host
spring.activemq.broker-port
spring.activemq.user
spring.activemq.password

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM