上一次有人说这个单机版还有一些问题,
问题一:
每一次都要自己写beanName , 但是ioc 容器那么多的bean 的名字, 我怎么记得住。
问题二:
一个配置文件key可以在多个bean对象 里面使用。 我这个只是一对一的绑定,不太适用。
今天我们就来解决这两个问题,
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, Object.class);
这个类是获取bean 的所有的对象, 返回的是map 。key 是 bean 的名字, value 就是一些bean对象。
我们在把他转换成
Map<String, List<String>>
key 是bean 对象名称, value 是这个bean 对象属性上面@value 的值的集合。
具体代码:
private static Map<String, List<String>> beanMaps = new HashMap<>();
//在bean 加载完成的时候执行
@PostConstruct
public void initialize() {
Map<String, Object> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, Object.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
String mapKey = entry.getKey();
Object mapValue = entry.getValue();
// 获取真实对象属性
Field[] declaredFields = mapValue.getClass().getDeclaredFields();
boolean cglib = Arrays.stream(declaredFields).anyMatch(x -> x.getName().contains("CGLIB"));
// 如果是cglib 代理找其父类
if(cglib){
declaredFields = mapValue.getClass().getSuperclass().getDeclaredFields();
}
List<String> collect = Arrays.stream(declaredFields).filter(x -> x.isAnnotationPresent(Value.class)).map(x -> x.getAnnotation(Value.class).value()).collect(Collectors.toList());
if(!ObjectUtils.isEmpty(collect)){
beanMaps.put(mapKey,collect);
}
}
}
/**
* 获取bean 的名称集合
* @param beanMaps
* @param key
* @return
*/
public List<String> getBeanName(Map<String, List<String>> beanMaps, String key) {
List<String> beanName = new ArrayList<>();
for (Map.Entry<String, List<String>> entry : beanMaps.entrySet()) {
if (entry.getValue().stream().anyMatch(x->x.contains(key))) {
beanName.add(entry.getKey());
}
}
return beanName;
}
测试类:
@PostMapping("private/reSetProperties")
public Map<String, Object> reSetProperties(@RequestBody Map<String, Object> map) {
SpringUtils.refreshEnvironment(map, configurableEnvironment);
map.keySet().stream().forEach( x->{
List<String> beanNames = getBeanName(beanMaps, x);
for (String beanName: beanNames){
Object bean = SpringContextUtil.getBean(beanName);
SpringUtils.refreshBean(bean, configurablePropertyResolver);}
}
);
return Response.customSuccessResponse(" 刷新成功");
}
测试:
这样就解决上面的两个问题了, 完美。喜欢,点赞,转发。