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

nacos+getbean的坏习惯 引发 AnnotationConfigApplicationContext has been closed,第1张

前言

每次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去来做线程间数据隔离,必须要理解整个,否则就是乱来;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/920514.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存