Nice programing

@PropertySource 주석을 사용할 때 @Value가 확인되지 않습니다.

nicepro 2020. 12. 27. 20:45
반응형

@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를 사용하고 싶습니다.


@PropertySource를 사용하는 경우 다음을 사용하여 속성을 검색해야합니다.

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

@Value ( "$ {mail.subject}")로 검색하려면 xml로 prop 자리 표시자를 등록해야합니다.

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


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

}

나는 그 이유를 찾을 @value나를 위해 작동하지 않는,되고 @value필요 PropertySourcesPlaceholderConfigurer대신의 PropertyPlaceholderConfigurer. 나는 똑같은 변경을했고 그것은 나를 위해 일했으며 봄 4.0.3 릴리스를 사용하고 있습니다. 내 구성 파일에서 아래 코드를 사용하여 구성했습니다.

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

@PropertySource를 Spring에 등록하기 위해 @Bean 주석이 달린 PropertySourcesPlaceholderConfigurer를 반환하고 정적 인 @Configuration 클래스의 메서드가 필요하지 않습니까?

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

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


나는 똑같은 문제가 있었다. @PropertySource와 잘 어울리지 않습니다 @Value. 빠른 해결 방법은 @ImportResource평소와 같이 Spring Java 구성에서 참조 할 XML 구성을 갖는 것 입니다. 해당 XML 구성 파일에는 단일 항목이 포함됩니다 <context:property-placeholder />(물론 필요한 네임 스페이스 행사 포함). 다른 변경 사항 @Value없으면 @Configurationpojo에 속성이 삽입됩니다 .


이것은 또한 이런 식으로 Java에서 구성 할 수 있습니다.

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

엄청나게 복잡해 보이는데 그냥 할 수 없니

 <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이전과 같이 주입하십시오.


문제는 다음과 같습니다. <util : propertes id = "id"location = "loc"/>는

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

(see documentation of util:properties). Thus, when you use util:properties, a standalone bean is created.

@PropertySource, on the other hand, as documentation says is an

annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment'.

(see @PropertySource doc). So it doesn't create any bean.

Then "#{a['something']}" is a SpEL expression (see SpEL), that means "get something from bean 'a'". When util:properties is used, the bean exists and the expression is meaningful, but when @PropertySource is used, there is no actual bean and the expression is meaningless.

You can workaround this either by using XML (which is the best way, I think) or by issuing a PropertiesFactoryBean by yourself, declaring it as a normal @Bean.


Since Spring 4.3 RC2 using PropertySourcesPlaceholderConfigurer or <context:property-placeholder> is not needed anymore. We can use directly @PropertySource with @Value. See this Spring framework ticket

I have created a test application with Spring 5.1.3.RELEASE. The application.properties contains two pairs:

app.name=My application
app.version=1.1

The AppConfig loads the properties via @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 {

}

The Application injects the properties via @Value and uses them.

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

The output is:

$ 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

Another thing that may be happening: ensure your @Value annotated values are not static.

ReferenceURL : https://stackoverflow.com/questions/13728000/value-not-resolved-when-using-propertysource-annotation-how-to-configure-prop

반응형