添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

这几天在对一个老项目做底层存储迁移,由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,直接作为属性注进去,不然的话还真不知道怎么解决,望大侠指点迷津。

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

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

@Autowired注入的对象执行方法报空指针 为什么,正常来说是有这个对象的,输出相关日志发现在用到一些变量的时候会导致这个 问题 。 那就是加了@Service,@Controller,@Component的注解后的类的静态属性,(也就是加了static关键字,属于这个类的成员变量)。 为什么呢? 因为 Spring 启动以后, 初始化 容器 的时候,会先把加了@Component,@Bean,@Service,@Controller,@Repository注解的类,加入到 Spring 初始化 容器 , 那么就会加载到
问题 描述     项目 使用quartz创建了一个定时任务,在系统启动后立即执行,我发现项目在启动 过程 ,会执行4次这个定时任务,也就是说项目被 初始化 了4次,这样会导致与任务相关的点出 问题     最初我是现从精简 Spring Spring MVC的配置开始入手 解决 这个 问题 的,精简完成后由 初始化 4次降为了两次,后来又通过配置tomcat将初...
以下是工作 过程 常见的一些 Spring 容器 启动时错误整理,方便后期再次遇到的时候,能够快速查询。本文章将不定时长期更新 1、NoSuchBeanDefinitionException org. spring framework.beans.factory.BeanCreationException:Error creating bean with name 'xxx.xxx.xxx': Inje...
30-Nov-2021 20:28:15.419 严重 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ContainerBase.removeChild ContainerBase.removeChild: destroy: org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before.. 1. 加载配置文件: Spring 通过读取配置文件(如 XML 文件或注解)来获取有关 bean 的信息。 2. 创建 BeanFactory 容器 Spring 使用 BeanFactory 接口来创建一个 容器 ,该 容器 用于管理 bean。 3. 向 容器 注册 Bean:在 容器 注册所有的 bean。 4. Bean 实例化: Spring 容器 调用每个 bean 的构造函数,创建 bean 的实例。 5. Bean 依赖注入:在 bean 实例创建后, Spring 容器 负责为每个 bean 设置其所需的依赖。 6. Bean 初始化 :在所有的依赖被注入后, Spring 容器 调用 bean 的 初始化 方法(如使用 @PostConstruct 注解的方法),使 bean 可以开始提供服务。 这些步骤构成了 Spring 的 bean 初始化 过程