@Value не разрешен при использовании аннотации @PropertySource. Как настроить 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 для настройки.

9 51

9 ответов:

Если вы используете @PropertySource, свойства должны быть получены с помощью:

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

Если вы хотите получить с @Value ("${mail.subject}"), вы должны зарегистрировать заполнитель prop с помощью xml.

причина: 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. Я сделал те же изменения, и это сработало для меня, я использую spring 4.0.3 release. Я настроил это с помощью кода ниже в моем файле конфигурации.

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

разве вам не нужен метод в вашем классе @Configuration, который возвращает PropertySourcesPlaceholderConfigurer, аннотированный @Bean и статический, чтобы зарегистрировать любой @PropertySource с Spring?

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

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

у меня была та же самая проблема. @PropertySource не очень хорошо играет с @Value. Быстрый обходной путь-иметь конфигурацию XML, которую вы будете ссылаться на нее из своей конфигурации Spring Java с помощью @ImportResource как обычно, и этот XML-файл конфигурации будет содержать одну запись:<context:property-placeholder /> (конечно, с необходимой церемонией пространства имен). Без каких-либо других изменений @Value введет свойства в ваш @Configuration pojo.

Это также может быть настроено в 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;

куда-нибудь.свойства выглядит примерно так

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

для конфигурации на основе java вы можете сделать это

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

а затем просто ввести с помощью @value, а перед

дело в том, что, насколько я понимаю, , это просто сокращение для

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

(см. документация util: properties). Таким образом, при использовании util:properties создается автономный компонент.

@PropertySource, с другой стороны, как говорится в документации, это

аннотация, обеспечивающая удобный и декларативный механизм для добавление PropertySource в Spring Окружающая среда".

(см. @PropertySource doc). Поэтому он не создает никаких бобов.

тогда" #{a['something']} " - это выражение SpEL (см. SpEL), что означает " получить что-то от bean 'a'". Когда используется util: properties, Боб существует, и выражение имеет смысл, но когда используется @PropertySource, нет фактического Боба, и выражение бессмысленно.

вы можете обойти это либо с помощью XML (что является лучшим способом, я думаю) или путем выдачи PropertiesFactoryBean самостоятельно, объявив его как обычный @Bean.

еще одна вещь, которая может произойти: убедитесь, что ваши @Value аннотированные значения не являются статическими.