在Spring应用程序中,我希望能够更改application.proporties的内容,并将这些更改传播到由 @Value 注释的所有bean值。
我知道我可以简单地重新加载所有Spring上下文,但我不想这样做。某些组件无法重新创建。我想仅为选择的豆子比例重新加载值。
我正在使用 Spring 3.2
我原型化自己的解决方案,但它需要在一些Spring内部类上使用反射。我正在寻找更清晰的解决方案
获取所需的内部Sping对象并创建我需要的公共方法/字段:
TypeConverter typeConverter = beanFactory.getTypeConverter();
// get object which store autowiring metadata for beans
Object annotationProcessor = beanFactory
.getSingleton("org.springframework.context.annotation.internalAutowiredAnnotationProcessor");
// let it be public for my usage
Method findMethod = ReflectionUtils.findMethod(AutowiredAnnotationBeanPostProcessor.class ,"findAutowiringMetadata", Class.class);
ReflectionUtils.makeAccessible(findMethod);
// let it be public for my usage
Field checkedElements = ReflectionUtils.findField(InjectionMetadata.class, "checkedElements");
ReflectionUtils.makeAccessible(checkedElements);
迭代所有bean并使用我自己的注释(@Reloadable)搜索元素。然后为它们重新加载值
for (String name : allBeanNames) {
Object bean = beanFactory.getSingleton(name);
InjectionMetadata metadata = (InjectionMetadata) findMethod.invoke(
annotationProcessor, bean.getClass());
@SuppressWarnings("unchecked")
Set<InjectedElement> elements = (Set<InjectedElement>) checkedElements
.get(metadata);
for (InjectedElement element : elements) {
Member member = element.getMember();
// check for each elements if it has my own annotation which
// means that it should be realoaded
// check removed for simplify
// get new value and load it
String placeholder = valueAnnotation.value();
String resolvedValue = env.resolvePlaceholders(placeholder);
Object converted = typeConverter.convertIfNecessary(
resolvedValue, type, field);
// load value
if (member instanceof Method) {
((Method) member).invoke(bean, converted);
} else if (member instanceof Field) {
((Field) member).set(bean, converted);
}
}
}
http://www.wuenschenswert.net/wunschdenken/archives/107 - 适用于旧版本的弹簧