最近用Spring的Task定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此。
打印出他们的hashcode,发现是不一样的,也就是说,在web容器启动的时候,重复启了两个线程。
研究下来发现确实会加载两次:
第一次:web容器启动的时候,读取applicationContext.xml文件时,会加载一次。
第二次:Spring本身会加载applicationContext.xml一次。
而我的task配置就是写在applicationContext.xml文件里的。
解决方案:
把task的配置单独拿出来
然后修改web.xml,让web容器启动时,可以加载该文件
1.创建applicationContext-task.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
<!--<context:component-scan base-package="com.efiles.box.controller" />-->
<!--任务调度器-->
<task:scheduler id="taskScheduler" pool-size="1" />
<task:annotation-driven executor="taskScheduler" proxy-target-class="true" />
</beans>
2.web.xml中的配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/applicationContext.xml,classpath:spring/applicationContext-task.xml
</param-value>
</context-param>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!-- 开启监听 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
3.创建一个类,5s执行一次
@Scheduled(cron = "0/5 * * * * ?")
public void runfirst(){
System.out.println("********first job is ok******" +System.currentTimeMillis());
}