web-dev-qa-db-ja.com

Spring Boot-環境@AutowiredがNullPointerExceptionをスローする

Spring Boot 0.5.0.M5を使用してプロジェクトをセットアップしています。

構成ファイルの1つで@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しかし、これまでのところ何も機能していません。助けていただければ幸いです。ありがとう。

15
imme

SpringとEntityManagerFactoryにはライフサイクルの問題があり、それらのファウルに陥ったかもしれません(4.0.0.RC1で修正済み)-@Configurationクラスは非常に早くインスタンス化されるため、自動配線の対象にならない場合があります。その場合は、おそらくログ出力から判断できます。

JpaConfigPropertyConfigが提供する機能は、@EnableAutoConfiguration (あなたが〜をするなら @ComponentScanリポジトリが定義されているパッケージ)?例については、 Spring BootのJPAサンプル を参照してください。

6
Dave Syer

特定の問題は解決しましたが、Springの自動配線が遅すぎる場合にEnvironmentを取得する方法は次のとおりです

秘trickは_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_ほどエレガントではありませんが、状況によっては回避策として機能します。

23
Alex Shesterov

私は春のブートアプリケーションで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
2
Nallamachu

Spring Batchでも同じ問題がありました。構成クラスが以前にインスタンス化されたため、ライターは環境クラスを自動配線できません。そのため、環境をインスタンス化するための一種のシングルトン(旧式)を作成し、毎回それにアクセスできました。

私はこの実装を行いました:

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

}

そしてそれは動作します

2
Greg Florance