web-dev-qa-db-ja.com

@PropertySourceアノテーションを使用すると、@ Valueは解決されません。 PropertySourcesPlaceholderConfigurerを構成する方法は?

次の構成クラスがあります。

@Configuration
@PropertySource(name = "props", value = "classpath:/app-config.properties")
@ComponentScan("service")
public class AppConfig {

そして私はプロパティでサービスを提供しています:

@Component 
public class SomeService {
    @Value("#{props['some.property']}") private String someProperty;

AppConfig構成クラスをテストするときにエラーが発生します

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private Java.lang.String service.SomeService.someProperty; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'props' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' 

この問題は文書化されています SPR-8539で

とにかく私はそれを動作させるためにPropertySourcesPlaceholderConfigurerを設定する方法を理解できません。

編集1

このアプローチはxml構成でうまく機能します

<util:properties id="props" location="classpath:/app-config.properties" />

ただし、構成にはJavaを使用します。

55
matus

@PropertySourceを使用する場合、プロパティは次の方法で取得する必要があります。

@Autowired
Environment env;
// ...
String subject = env.getProperty("mail.subject");

@Value( "$ {mail.subject}")で取得したい場合、xmlでpropプレースホルダーを登録する必要があります。

理由: https://jira.springsource.org/browse/SPR-8539

30
laffuste

@cwashが言ったように。

@Configuration
@PropertySource("classpath:/test-config.properties")
public class TestConfig {

     @Value("${name}")
     public String name;


     //You need this
     @Bean
     public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
     }

}
122
baybora.oren

理由を見つけた@value私のために働いていませんでした、@valueにはPropertySourcesPlaceholderConfigurerの代わりにPropertyPlaceholderConfigurerが必要です。私は同じ変更を行い、それは私のために働いた、私は春4.0.3リリースを使用しています。構成ファイルの以下のコードを使用してこれを構成しました。

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
   return new PropertySourcesPlaceholderConfigurer();
}
16

@PropertySourceをSpringに登録するために、PropertySourcesPlaceholderConfigurerを返し、静的である@Configurationクラスのメソッドが必要ではありませんか?

http://www.baeldung.com/2012/02/06/properties-with-spring/#Java

https://jira.springsource.org/browse/SPR-8539

11
cwash

私はまったく同じ問題を抱えていました。 @PropertySource@Value。簡単な回避策は、Spring Java Configuration using @ImportResource通常どおり、そのXML構成ファイルには単一のエントリが含まれます:<context:property-placeholder />(もちろん、必要な名前空間セレモニーを使用)。他の変更なし@Valueはあなたの@Configuration pojo。

6
dimitrisli

これはJavaこの方法で設定することもできます

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    configurer.setIgnoreUnresolvablePlaceholders(true);
    configurer.setIgnoreResourceNotFound(true);
    return configurer;
}
4
Gowtham

それは非常に複雑に見えます、あなたはちょうどできません

 <context:property-placeholder location="classpath:some.properties" ignore-unresolvable="true"/>

次に、コードリファレンスで:

@Value("${myProperty}")
private String myString;

@Value("${myProperty.two}")
private String myStringTwo;

some.propertiesは次のようになります

myProperty = whatever
myProperty.two = something else\
that consists of multiline string

Javaベースの設定の場合、これを行うことができます

@Configuration
@PropertySource(value="classpath:some.properties")
public class SomeService {

そして、以前と同様に@valueを使用して注入するだけです

3
NimChimpsky

問題は、私が知る限り、<util:propertes id = "id" location = "loc" />は、

<bean id="id" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="loc"/>
</bean>

til:propertiesのドキュメント を参照)。したがって、util:propertiesを使用すると、スタンドアロンBeanが作成されます。

一方、@ PropertySourceは、ドキュメントにあるように、

propertySourceをSpringの環境に追加するための便利で宣言的なメカニズムを提供するアノテーション。

@ PropertySource doc を参照)。したがって、Beanは作成されません。

次に、「#{a ['something']}」はSpEL式( SpEL を参照)、つまり、「bean 'a'から何かを取得する」ことを意味します「。 util:propertiesを使用すると、Beanは存在し、式は意味を持ちますが、@ PropertySourceを使用すると、実際のBeanは存在せず、式は無意味になります。

これを回避するには、XMLを使用するか(最善の方法だと思います)、または自分でPropertiesFactoryBeanを発行して、通常の@Beanとして宣言します。

2
Artem Shitov

Spring 4.3 RC2では、PropertySourcesPlaceholderConfigurerまたは<context:property-placeholder>を使用する必要がなくなりました。 @PropertySourceで直接@Valueを使用できます。こちらをご覧ください Spring framework ticket

Spring 5.1.3.RELEASEでテストアプリケーションを作成しました。 application.propertiesには2つのペアが含まれます。

app.name=My application
app.version=1.1

AppConfigは、@PropertySourceを介してプロパティをロードします。

package com.zetcode.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "application.properties", ignoreResourceNotFound = true)
public class AppConfig {

}

Applicationは、@Valueを介してプロパティを注入し、それらを使用します。

package com.zetcode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.zetcode")
public class Application {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    @Value("${app.name}")
    private String appName;

    @Value("${app.version}")
    private String appVersion;

    public static void main(String[] args) {

        var ctx = new AnnotationConfigApplicationContext(Application.class);
        var app = ctx.getBean(Application.class);

        app.run();

        ctx.close();
    }

    public void run() {

        logger.info("Application name: {}", appName);
        logger.info("Application version: {}", appVersion);
    }
}

出力は次のとおりです。

$ mvn -q exec:Java
22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application name: My application
22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application version: 1.1
1
Jan Bodnar

発生する可能性のある別のこと:@Valueアノテーション付きの値が静的でないことを確認してください。

0
davo