Следующее немного странно, но работает.Вы создаете пользовательскую область с именем reconfigurable
, которая выбрасывает все компоненты, созданные в этой области, при каждом обновлении конфигурации.Таким образом, свежий бин будет создан после изменения конфигурации.
Фактические значения конфигурации должны быть получены с помощью языка выражений Spring, поскольку значения как для обычного синтаксиса $ {}, так и для PropertyOverrideConfigurer, по-видимому, постоянно фиксируются вBeanDefinition.Объявление bean-компонента для bean-компонента с переконфигурируемым свойством someProperty
выглядит следующим образом:
<bean class="blablu.Testbean" scope="reconfigurable"
p:someProperty="#{ config['configexplicit']}">
<aop:scoped-proxy />
</bean>
Вам необходимо использовать aop: scoped-proxy, чтобы bean-компоненты, использующие этот bean-компонент, всегда получали самый свежий сконфигурированный bean-компонент.из пользовательской области.
Объявление свойств с помощью @Value
также работает;если вы используете компонентное сканирование, вам нужно объявить область с аннотацией
@Scope(value="reconfigurableScope", proxyMode=ScopedProxyMode.TARGET_CLASS)
Если вам нужны подробности: основная идея области:
public class ReconfigurableScope implements Scope {
private final Map<String, Object> nameToObjectMap = new ConcurrentHashMap<String, Object>();
public Object get(final String name, final ObjectFactory<?> objectFactory) {
Object bean = nameToObjectMap.get(name);
if (null == bean) {
bean = objectFactory.getObject();
nameToObjectMap.put(name, bean);
}
return bean;
}
// called from outside on each configuration change
public void update(final ConfigurationObservable observable, final Object arg) {
nameToObjectMap.clear();
}
}
Плюс некоторая безопасность потокаи очистить вещи: удаленные bean-компоненты должны быть уничтожены немного позже, а контекст приложения закрыт.