@Scheduled定时器同时执行两次的情况 注解定时不允许带参数

1、在用spring里面的@Scheduled执行定时任务,但是发现到触发定时任务的时间点总会执行两次。开始一直以为是spring配置         出了问题。后面换了一台主机,在里面的tomcat跑了程序,只执行了一次。后面可以定位了,说明代码和spring配置是没有        问 题的,是tomcat配置出了问题。后面在网上查了一些资料,定位到是以前自己修改了service.xml导致的。配置如下:   

<Host name="localhost"  appBase="/wls/apps" unpackWARs="false" autoDeploy="true">

<Context path="" docBase="/wls/apps/backup" reloadable="true"></Context>

    这样配置相当于tomcat容器加载了两次应用。后面将appBase="/wls/apps" 改为appBase=""问题成功解决了。

    以前自己也是这样配置tomcat的,正纳闷为什么请求的url后面加不加上应用名都能请求应用,如:

    hostIP:8080 和hostIP:8080/backup都能请求应用,原来tomcat里面本来就加载了两个的应用。加上应用名对应的是appBase下面应用,不加应用名对应的是docBase。

网上还有一种可能不知道对不对,这里说一下:

对监听器Listener和上下文对象contextConfigLocation和DispatcherServlet的配置, 出错原因就是没有设置contextConfigLocation为空,导致加载了两次配置文件,所以就有两个操作的上下文的session出现。把上面的代码添加一段即可:
 

<!--
        The Bootstrap listener to start up and shut down Spring's root
        WebApplicationContext. It is registered to Servlet Container
    -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
 
 
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>
 
    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加上了这个 定时器就不会同时执行两次了-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
 
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

2、<Context>元素的属性: 

path:指定访问该Web应用的URL入口。 

docBase:指定Web应用的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBase属性的相对路径,如果Web应用采用开放目录结构,则指定Web应用的根目录,如果Web应用是个war文件,则指定war文件的路径。(指定项目所在地址) 

reloadable:如果这个属性设为true,tomcat服务器在运行状态下会监视在WEB-INF/classes和WEB-INF/lib目录下class文件的改动,如果监测到有class文件被更新的,服务器会自动重新加载Web应用。

3、关于appBase和docBase的区别:

<host appBase="d:/aaa">
<Context path="/smswap" reloadable="true" docBase="D:\workspace\smswap\WebRoot"></Context>
</host>

我们先看appBase,这个目录表示:
1 这个目录下面的子目录将自动被部署为应用。
2 这个目录下面的.war文件将被自动解压缩并部署为应用

而docBase只是指向了你某个应用的目录,这个可以和appBase没有任何关系。

总结:
如果你想自己指定路径,那么应该在docBase里面
如果你想简单,那么直接把他们复制到appBase下面就行了

如果你把他们弄重复了,也就是2个指向了一个目录,看上去也能运行,但你的应用下面的每个子目录,其实是被部署为单独的应用的。
比如你的应用为

myApp, 放在了
d:\project\myApp
里面有2个子目录
d:\project\myApp\images
d:\project\myApp\js

你可以通过
1 设置 appBase 指向 d:\project 来让系统自动部署
2 你可以手工指定docBase到 d:\project\myApp
3 如果你指定了 appBase到 d:\project\myApp 那么
d:\project\myApp\images这个将不再是普通的子目录,而是一个单独的虚拟目录,或者叫应用了。因为其被自动部署
d:\project\myApp\js 也一样的后果
 

ubuntu下的tomcat,由于没有深入分析过tomcat/conf/server.xml,遇到很多问题。

    一开始总是把appBase配置成应用程序的路径,结果反复的修改别处,也没搞定,突然想起docBase,然后在

    appBase 下面加了一行docBase,把路径配置到docBase中,把appBase为空,就OK了

      <Host name="localhost"  appBase=""
           unpackWARs="true" autoDeploy="true"
           xmlValidation="false" xmlNamespaceAware="false">

       <Context path="" docBase="/usr/local/webapp" debug="0" reloadable="true" crossContext="true"/>
--------------------- 
作者:liuxuejin 
来源:CSDN 
原文:https://blog.csdn.net/liuxuejin/article/details/9104055 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/liutianjie/article/details/86494002
今日推荐