栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

nacos+getbean的坏习惯 引发 AnnotationConfigApplicationContext has been closed

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

nacos+getbean的坏习惯 引发 AnnotationConfigApplicationContext has been closed

前言

每次nacos发布新的config的时候,接下来就会发生一个很诡异的情况,AnnotationConfigApplicationContext has been closed

过程

百度了一圈,有类似的问题,但是没有相关的解决方案;于是我就开始关注AnnotationConfigApplicationContext这个类,既然你说它管理了,说明我是哪里使用了,最后发现是因为我们使用了springutil.getbean,这个玩意就是用于不按照注解的方式去获取bean的过程;正常在main里面去run上下文没啥问题;

        ConfigurableApplicationContext context = SpringApplication.run(XXXApplication.class, args);
        // application 里面配置一个新的注册方式
        // 这种方式,单元测试也是可以用的。
        // 所以这里被重复设置了
        SpringContextUtil.setApplicationContext(context);

其实我们就发现了这里,我们自己setApplicationContext用于后面做getbean使用;这种大家百度都能百度的到,但是都是建议不要大量乱用,非必要不要用;

但是我们团队里,就有这么一位不听话的大佬(之前写php的);大量使用了getbean这本也没什么;但是他要单元测试,发现@value注解引入不了配置文件了,于是他使用了

context:
  initializer:
    classes: com.cs.xxx.common.ApplicationContextInitializerCustom

然后这个类又是怎么写的呢

public class ApplicationContextInitializerCustom implements org.springframework.context.ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext context) {
        SpringContextUtil.setApplicationContext(context);
    }
}

这就引发了问题,他也用了setApplicationContext,并且在init的时候,引入了配置;为了单元测试用;
谁也没想到,他的这次set会因为nacos的发布,配置的读取,将我们context给重置了。但是实际上执行完run之后,这个上下文其实会自动关闭;这时用这个上下文来getbean,对不起它已经挂了;

总结

1、用什么语言就要遵循他的逻辑,不要用写java的方式去写php,也不要用写php的方式来写java;自以为很牛逼,其实啥也不懂;如果不是因为乱用getbean不会必须要注入配置,也就不会引发这次nacos的更新问题;因为一个乱用,导致2次需要解决的痛点,会不会引发第三次还不确认
2、php本身就是进程安全的,他解决不了进程间共享的问题,所以要借助于redis等之类的工具来做进程间数据传输;而java本身就是线程不安全的,需要通过threadlocal去来做线程间数据隔离,必须要理解整个,否则就是乱来;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/877055.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号