@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 для конфигурации.
Ответы
Ответ 1
Если вы используете @PropertySource, свойства должны быть получены с помощью:
@Autowired
Environment env;
// ...
String subject = env.getProperty("mail.subject");
Если вы хотите получить с помощью @Value ( "$ {mail.subject}" ), вам необходимо зарегистрировать местозадержатель прошивки по xml.
Причина:
https://jira.springsource.org/browse/SPR-8539
Ответ 2
как сказал @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();
}
}
Ответ 3
Я обнаружил, что причина @value
не работает для меня, @value
требует PropertySourcesPlaceholderConfigurer
вместо PropertyPlaceholderConfigurer
. Я сделал те же изменения, и это сработало для меня, я использую spring 4.0.3 выпуск. Я сконфигурировал это, используя код ниже в моем файле конфигурации.
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Ответ 4
Вам не нужен метод в классе @Configuration, который возвращает PropertySourcesPlaceholderConfigurer, аннотированный @ Bean и является статическим, чтобы зарегистрировать любой источник @PropertySource с помощью Spring?
http://www.baeldung.com/2012/02/06/properties-with-spring/#java
https://jira.springsource.org/browse/SPR-8539
Ответ 5
У меня была такая же проблема. @PropertySource
не работает с @Value
. Быстрое обходное решение состоит в том, чтобы иметь конфигурацию XML, которую вы будете ссылаться на нее из вашей конфигурации Spring Java, используя @ImportResource
, как обычно, и что файл конфигурации XML будет содержать одну запись: <context:property-placeholder />
(конечно же, с необходимым пространством имен церемония). Без каких-либо других изменений @Value
будет вводить свойства в ваш @Configuration
pojo.
Ответ 6
Это также можно настроить в java таким образом
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setIgnoreUnresolvablePlaceholders(true);
configurer.setIgnoreResourceNotFound(true);
return configurer;
}
Ответ 7
Это выглядит очень сложно, не можете ли вы просто сделать
<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
, как раньше
Ответ 8
Дело в том, что, насколько я понимаю, < util: propertes id = "id" location = "loc" / > , является просто сокращением для
<bean id="id" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="loc"/>
</bean>
(см. документация утилиты: свойства). Таким образом, при использовании свойств util: создается автономный bean.
@PropertySource, с другой стороны, как говорится в документации,
аннотация, обеспечивающая удобный и декларативный механизм для добавив свойство PropertySource в Spring Environment '.
(см. @PropertySource doc). Поэтому он не создает никаких bean.
Затем "# {a ['something']}" является выражением SpEL (см. SpEL), что означает "получить что-то из bean 'a'". Когда используется: свойства используются, существует bean, и выражение имеет смысл, но когда используется @PropertySource, фактического bean нет, и выражение бессмысленно.
Вы можете обойти это либо с помощью XML (что лучше всего, я думаю), так и путем создания свойства PropertiesFactoryBean, объявив его как обычный @ Bean.