spring容器被多次初始化问题排查及解决

这几天在对一个老项目做底层存储迁移,由oracle改为mysql,在此期间发现一个问题,导致tomcat启动报错。

问题描述:本地eclipse启动tomcat发布项目,从日志中可以看到,spring被初始化了四次!由于spring多次初始化,导致资源被重复加载,这将带来一系列问题,比如定时任务执行两次等等,我遇到的两个明显的报错是Druid注册数据源的时候,说已存在的数据源,也就是重复注册了,还有一个是metaq producer group在第二次创建的时候报错,说是之前已经创建过了,上图吧,更直观些;

第一次初始化spring容器:


第二次初始化spring容器:


第二次初始化的时候,德鲁伊(使用了tddl数据库中间件)注册数据源的时候就报错了,从异常的字面意思就很明显的知道,是数当前注册的数据源已经存在,也就是重复注册了;

第二次初始化spring容器引起的metaq生产者组重复创建的异常信息如下:


不要太在意这两个异常,只是spring重复初始化带来的问题的两个小例子,其实这两个问题不影响项目正常运行,metaq这个异常其实在刚集成metaq的时候就已经发现了,而且也知道是因为spring初始化两次引起的,因为小伙伴的惰性,时间因素及不影响正常运行,就没有去深究初始化两次的原因,就像开发答应产品“该功能在二期会实现”一样,然后就没有然后了。。。然而这次数据库切换,又冒出来了一个报错,这样下去不行的,还是解决了吧。

排查过程:

1、首先想到是否spring配置有问题,经排查没有问题。

2、发到开发服务器上看下,噢,有发现,本地eclipse中启动tomcat的初始化四次,而发布到服务器上变成了两次。

那么本地直接发不到tomcat下面呢,不经过eclipse,直接打成war包,扔到tomcat webapps目录下,不改任何配置,直接启动,嗯,有点意思,初始化了两次,那么其中的两次初始化就是在eclipse上启动tomcat引起的了,虽然缩小了范围,但是没遇到过这种问题呢,为什么在eclipse中启动会初始化两次,真心不知道,求助万能的度娘(不要鄙视我,不是不用谷歌,是懒得翻墙,度娘能解决的何必那么麻烦),还挺好使,因为我把项目的context root改成了/,我又习惯于把tomcat的发布目录改为webapps目录,如下图:



这样,tomcat启动的时候,先发布一次webpps下面的/xxx,然后再发布一次/,所以发布了两次,spring自然就被初始化了两次,问题找到了,怎么解决呢:

网上有多种解决方法,只说一种简单有效的办法,tomcat发布目录,改在其他目录,不要发布在webapps目录下,就是这么简单:


改完之后,再启动,初始化四次,变成了两次,还有两次,继续排查。。。

3、spring配置没有问题,因为没有方向,万能的度娘也帮不上忙了,怎么办?

开启debug级别日志看看,看下初始化过程!为什么一开始没有开debug日志呢,因为我还是比较讨厌debug日志的,打的日志太多太多,很容易掩盖想要看的信息,但是不得不承认,它是一个很好的排查问题的手段!果然有惊喜:


按顺序初始化Filter的时候,发现初始化sessionFilter,竟然引起了spring的初始化,看来问题就在这了,为什么会引起spring初始化呢,打开这个过滤器的初始化代码看一下:


呵呵 ..呵呵..呵呵!

相信大家都知道怎么回事了!日志中也打印了有相关信息,new ClassPathXmlApplicationContext("spring/application_context_service.xml")代码中直接加载了一遍spring!

怎么改呢:网上各种方式,总的方向就是从已有的容器中获取想要的bean,这里给个链接http://blog.csdn.net/budapest/article/details/38493003,感谢博主,本文不在重复造轮子。

但是网上的各种方式,对Filter来说,并没有什么卵用(试了各种方法),因为filter加载的时候,还没有初始化spring。我的解决方法是把Filter换成了springmvc的拦截器,因为恰好用的springmvc,想要的bean,直接作为属性注进去,不然的话还真不知道怎么解决,望大侠指点迷津。



到此结束,内容有点啰嗦,没有直接针对问题和解决方法,只是想为新手传达一些排查问题的思路。

第一篇博客,希望以后能够养成习惯!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值