前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot@value 动态刷新2 单机版

Springboot@value 动态刷新2 单机版

作者头像
分享干货的你
发布2021-04-23 11:06:16
1.1K0
发布2021-04-23 11:06:16
举报
文章被收录于专栏:分享干货的你

上一次有人说这个单机版还有一些问题,

问题一:

每一次都要自己写beanName , 但是ioc 容器那么多的bean 的名字, 我怎么记得住。

问题二:

一个配置文件key可以在多个bean对象 里面使用。 我这个只是一对一的绑定,不太适用。

今天我们就来解决这两个问题,

代码语言:javascript
复制
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, Object.class);

这个类是获取bean 的所有的对象, 返回的是map 。key 是 bean 的名字, value 就是一些bean对象。

我们在把他转换成

代码语言:javascript
复制
 Map<String, List<String>>

key 是bean 对象名称, value 是这个bean 对象属性上面@value 的值的集合。

具体代码:

代码语言:javascript
复制
    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);
            }
        }
    }
代码语言:javascript
复制
    /**
     *  获取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;
    }

测试类:

代码语言:javascript
复制
@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(" 刷新成功");
    }

测试:

这样就解决上面的两个问题了, 完美。喜欢,点赞,转发。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 分享干货的你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档