查出来的解决方案,现在作一总结:
引发原因:定时器被启动了两次,重启了两个定时器线程(spring中timer定时器;quartz定时器);
第一次:web容器启动的时候,读取applicationContext.xml文件时,会加载一次。
第二次:Spring本身会加载applicationContext.xml一次。
根源定时器配置与其它spring配置全部写在applicationContext.xml文件里.
遗留问题:
web容器读取spring配置文件时是如何进行第一次加载定时器的?
解决方案:
1,通过程序设置标志变量方式改变,此种方式不建议,从根本上不能解决问题,不作介绍
2,将定时器配置从spring主配置文件中分离,进行分次加载定时功能只由web容器加载;
配置文件样例如下(spring用的是3.0,quartz用的是2.0):
web.xml配置文件主要涉及部分
<context-param>
<param-name>contextConfigLocation</param-name>
<!--spring主配置文件-->
<param-value>classpath:springConf/applicationContext.xml,
<!--Quartz定时器配置文件使用quartz时配置-->
classpath:springConf/timerQuartz-Context.xml,
<!--timer定时器配置文件使用spring timer时配置-->
classpath:springConf/timertask-Context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<display-name>springDispacher</display-name>
<servlet-name>springDispacher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springConf/applicationContext.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispacher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
主spring配置文件中说明applicationContext.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="datasource-Context.xml" />
<import resource="user-Context.xml" />
<import resource="app-Context.xml" />
<!--如果将定时器配置在这里或直接import进这里就会导致启动两次-->
<!--<import resource="timertask-Context.xml"/> -->
<!--<import resource="timerQuartz-Context.xml"/> -->
</beans>
顺利也复习一下定时器如何配置:
spring中timer定时器的配置方法timertask-Context.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--定时器任务的主类-->
<bean id="timerTask" class="business.timertask.action.TimerTaskAction">
<property name="taskService" ref="taskService"></property>
</bean>
<!--aop事物配置 -->
<bean id="taskServiceAop" parent="serviceAop">
<property name="target" ref="taskService"></property>
</bean>
<!--任务处理的业务类-->
<bean id="taskService" class="business.timertask.services.IMPTaskService">
<property name="taskDao" ref="taskDao"></property>
</bean>
<!--任务处理的dao类 -->
<bean id="taskDao" class="business.timertask.dao.IMPTaskDAO">
<property name="dataSource" ref="dataSource"></property>
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
<!-- 启动定时器 -->
<bean id="start" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>
<!--定时器启动参数配置-->
<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!--延迟2秒执行 -->
<property name="delay">
<value>2000</value>
</property>
<!--每3百秒执行一次 -->
<property name="period">
<value>300000</value>
</property>
<property name="timerTask" ref="timerTask"></property>
</bean>
</beans>
quartz定时器配置方法:timerQuartz-Context.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--调度工厂配置 -->
<bean id="schedulerFactory" class="org.quartz.impl.StdSchedulerFactory">
</bean>
<!--定时表达式 -->
<bean id="cronExc" class="org.quartz.CronExpression">
<constructor-arg>
<value>0/5 * * * * ?</value>
</constructor-arg>
</bean>
<!--表达式的触发器配置 -->
<bean id="cronTrigger" class="org.quartz.impl.triggers.CronTriggerImpl">
<!--触发器名 -->
<property name="name" value="cronTrigger" />
<!--触发器组 -->
<property name="group" value="cronTriggerGroup" />
<!--触发器执行参数,每5秒一次 -->
<property name="cronExpression">
<value>0/5 * * * * ?</value>
</property>
</bean>
<!--自定义任务类job -->
<bean id="customJob" class="business.timerTaskForQuatz.bean.CustomJob">
</bean>
<!--jobDetail类 -->
<bean id="jobDetail" class="org.quartz.impl.JobDetailImpl">
<!--jobDetail任务名 -->
<property name="name" value="cornJob" />
<!--jobDetail组名 -->
<property name="group" value="cornJobGroup" />
<!--自定义任务类job包classname -->
<property name="jobClass" value="business.timerTaskForQuatz.bean.CustomJob" />
</bean>
<!--quartz主类 -->
<bean id="quartzAction" class="business.timerTaskForQuatz.action.QuartzAction"
init-method="start">
<!--jobDetail类 -->
<property name="jobDetail" ref="jobDetail"></property>
<!--定时表达式 -->
<property name="cronExpression" ref="cronExc"></property>
<!--调度工厂-->
<property name="sFactory" ref="schedulerFactory"></property>
<!--触发器 -->
<property name="cronTrigger" ref="cronTrigger"></property>
</bean>
</beans>
项目源码
列出jar包附件图