Как получить значение свойства из объекта ApplicationContext? (без аннотации)

Если у меня есть:

@Autowired private ApplicationContext ctx;

Я могу получить компоненты и ресурсы с помощью одного из методов getBean. Однако я не могу понять, как получить значения свойств.

Очевидно, я могу создать новый bean-компонент со свойством @Value, например:

private @Value("${someProp}") String somePropValue;

Какой метод вызвать объект ApplicationContext, чтобы получить это значение без автоматического подключения bean-компонента?

Обычно я использую @Value, но бывает ситуация, когда выражение SPeL должно быть динамическим, поэтому я не могу просто использовать аннотацию.


person HappyEngineer    schedule 30.05.2012    source источник
comment
(YourBeanType) ctx.getBean (beanId);   -  person Todd Murray    schedule 30.05.2012


Ответы (3)


В случае, когда выражение SPeL должно быть динамическим, получите значение свойства вручную:

somePropValue = ctx.getEnvironment().getProperty("someProp");
person Italo Borssatto    schedule 19.04.2014
comment
Использование Environment во время выполнения (а не только при запуске) обычно является очень плохой идеей, поскольку оно проходит через JNDI и другие места в поисках значения, что дорого. - person kaqqao; 05.09.2015

Предполагая, что свойство ${someProp} происходит от PropertyPlaceHolderConfigurer, это усложняет задачу. PropertyPlaceholderConfigurer - это BeanFactoryPostProcessor и, как таковой, доступен только во время запуска контейнера. Таким образом, свойства недоступны для bean-компонента во время выполнения.

Решением было бы создать своего рода bean-компонент-держатель значения, который вы инициализируете нужным свойством / свойствами.

@Component
public class PropertyHolder{

    @Value("${props.foo}") private String foo;
    @Value("${props.bar}") private String bar;

    // + getter methods
}

Теперь вставьте этот PropertyHolder везде, где вам нужны свойства, и получите доступ к свойствам через методы получения.

person Sean Patrick Floyd    schedule 30.05.2012
comment
Здесь был бы очень полезен пример. - person Webnet; 25.09.2013
comment
@Webnet хорошо, добавлен небольшой пример - person Sean Patrick Floyd; 25.09.2013
comment
Разве для этого не требуется, чтобы PropertyHolder был управляемым компонентом? Я думаю, что @HappyEngineer искал решение, которое не является управляемым компонентом (как и я). - person Webnet; 25.09.2013
comment
@Webnet Я понимаю, но AFAIK это невозможно в Spring (по крайней мере, с механизмом PropertyPlaceholderConfigurer) - person Sean Patrick Floyd; 25.09.2013
comment
Ответ resolveEmbeddedValue () у меня работает с Spring 4.3.3. Требуется только контекст, а не заполнитель значения bean-компонента. - person Wheezil; 12.07.2019
comment
@Wheezil конечно. Обратной стороной является то, что это сообщает приложению о контейнере, что считается архитектурным запахом. Но если это работает для вас, дерзайте - person Sean Patrick Floyd; 12.07.2019
comment
@SeanPatrickFloyd согласился ... мой конкретный случай - модульное тестирование, где я могу избежать неприятностей. - person Wheezil; 16.07.2019

Если вы застряли на Spring pre 3.1, вы можете использовать

somePropValue = ctx.getBeanFactory().resolveEmbeddedValue("${someProp}");
person Asa    schedule 07.03.2015
comment
Это ответ, который подходит мне в Spring 4.3.3. Требуется только контекст, а не заполнитель значения bean-компонента. - person Wheezil; 12.07.2019