Spring定时器会初始化两次终于找到原因了!!!
创始人
2024-02-11 10:59:08
0

使用idea编译器中的Tomcat时写在逻辑业务层的定时器会执行两次,最开始我认为是Tomcat的问题,后面做了个测试在出现该现象的业务层类中定义了一个测试定时器方法:

@Scheduled(cron ="0/5 * * * * ?")  //每隔5秒执行一次这个方法public void test(){System.out.println(this);}

控制台输出:

可以看到该对象会输出两个不同地址,我意识到了该类被实例化了两次 ,在网上查找了相关信息,总结了出现该问题的原因:

 原因1.使用了Tomcat实例中的配置的应用程序,而其中的配置文件中的server.xml文件中的

 
 

appBase为webapp的同时下面的docBase不为空,为了查到原因,我特意去看了下HOST标签与Context标签代表的作用:
    元素
    作用:表示一个虚拟主机,为特定的虚拟主机处理所有请求
    元素
    作用:一个WEB应用程序,处理当前WEB应用程序的所有请求,每一个必须使用唯一的上下文路径。
    如果docBase指定的WAR包或应用目录就在docBase中,则不需要指定,因为Tomcat会自动扫描appBase中的WAR包和应用目录,指定了反而会造成问题。
    这也是有人会出现问题的所在,我看了下出现这个
    问题的小伙伴的配置docBase路径多是相对路径,Tomcat在执行时会出现扫描两次的时候,所以出现了两次或多次的初始化定时器

关于server.xml详解

原因2:没有使用了Tomcat实例中的配置的应用程序,会自动部署场景,配置文件多会自动部署,而自动部署的server.xml文件中的appBase值为webapps,没有docBase,但也会出现两次
初始化定时器,有人已经知道是容器的问题有的人,网上有的解释的是ContextLoaderListener与DispatcherServlet会创建出两个容器,这样会导致初始化两个bean,于是他们就删掉其中的一个,

其中的原理是什么呢?,我们先来简单看看ContextLoaderListener与DispatcherServlet两者的关系与区别:

ContextLoaderListener是上下文加载监听器用于加载应用中所有的bean,是父容器,

DispatcherServlet是前端控制器是用于对前端请求关系与对应的Controler层的bean对象的映射关系

他俩的关系:

ContextLoaderListener 创建根应用程序上下文
DispatcherServlet 条目为每个servlet条目创建一个子应用程序上下文。
子上下文可以访问根上下文中定义的bean。
根上下文中的Bean无法直接访问子上下文中的bean。
所有上下文都被添加到ServletContext。
你可以使用WebApplicationContextUtils类访问根上下文。

通过getbean获取bean时先回从子容器中查找,如果子容器没有就会去父容器,而查找的过程中会扫描相对应的配置文件,里面的扫描器多会开启扫描,将扫描到的bean转载到容器中,而SSM整合的过程中我们习惯将Spring与Springmvc配置文件合并为application.xml,正是因为这样在对,通过web.xml:

application.xml:

 会先在子容器中找,此时目的是为了去进行子容器的bean装箱,也就是去执行

也就是因为两个配置文件合并了在对子容器的bean装箱的时候开启了父容器的bean的装箱

这是因为定时器写在了除Control层的bean上,如持久层、逻辑业务层才会出现的错误,

而写在控制层却不会出现问题的原因了,现在大家知道出现这种情况的原因了吧。而上面讲的网友的解决方法是不全对的,如果你删掉的是DispatcherServlet,就会报一下错:

如果你删掉 ContextLoaderListener不会报错,定时器也只执行了一次,那么就是说明ContextLoaderListener没用咯?其实不然,因为在对子容器进行初始化的时候会对父容器进行初始化,在tomcat启动过程中,创建了DispatcherServlet,该servlet继承FrameworkServlet:

在这里插入图片描述

这里有个initServletBean方法,该方法会在tomcat启动时被调用!从而创建spring容器(WebApplicationContext),删除ContextLoaderListener和将两个配置文件分开写多测试成功:

 大功告成!!!

所以说其实两个容器多是应用程序的必须,以上就是 使用idea编译器中的Tomcat时写在逻辑业务层的定时器会执行两次的原因。

如果对你有用,那就:

 本文参考的资料有:

https://blog.csdn.net/qq_37063860/article/details/97275997

https://blog.51cto.com/u_15064650/3769909?b=totalstatistic

web.xml只需配置DispatcherServlet无需配置ContextLoaderListener的原因_Rico_Yip的博客-CSDN博客

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...