我有Quartz 2.2.1和Spring 3.2.2。 Eclipse Juno上的应用程序
这是我的bean配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Spring Quartz -->
<bean id="checkAndRouteDocumentsTask" class="net.tce.task.support.CheckAndRouteDocumentsTask" />
<bean name="checkAndRouteDocumentsJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="net.tce.task.support.CheckAndRouteDocumentsJob" />
<property name="jobDataAsMap">
<map>
<entry key="checkAndRouteDocumentsTask" value-ref="checkAndRouteDocumentsTask" />
</map>
</property>
<property name="durability" value="true" />
</bean>
<!-- Simple Trigger, run every 30 seconds -->
<bean id="checkAndRouteDocumentsTaskTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="checkAndRouteDocumentsJob" />
<property name="repeatInterval" value="30000" />
<property name="startDelay" value="15000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="checkAndRouteDocumentsJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="checkAndRouteDocumentsTaskTrigger" />
</list>
</property>
</bean>
我的mvc spring servlet config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
<mvc:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="net.tce" />
<import resource="spring-quartz.xml"/>
</beans>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>OperationalTCE</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
我的问题是,在启动我的应用程序时,Quartz会同时创建两个作业。我的工作必须每30秒执行一次:
INFO: Starting TASK on Mon Nov 04 15:36:46 CST 2013...
INFO: Starting TASK on Mon Nov 04 15:36:46 CST 2013...
INFO: Starting TASK on Mon Nov 04 15:37:16 CST 2013...
INFO: Starting TASK on Mon Nov 04 15:37:16 CST 2013...
INFO: Starting TASK on Mon Nov 04 15:37:46 CST 2013...
INFO: Starting TASK on Mon Nov 04 15:37:46 CST 2013...
感谢您的帮助。
答案 0 :(得分:2)
您的ContextLoaderListener
和DispatcherServlet
都加载了mvc-dispatcher-servlet.xml
。基本上复制所有bean,导致2次执行,因为它也是重复的。
将您的配置拆分为由ContextLoaderListener
(包含您的服务,dao,计时器等)加载的配置和由DispatcherServlet
加载的配置(仅包含与Web相关的bean控制器,查看resovlers)等)。
完全放弃ContextLoaderListener
,只使用DispatcherServlet
加载所有内容。
答案 1 :(得分:1)
确保您没有在项目的web.xml文件中加载这两个文件。如果单独加载spring-quartz.xml文件,然后分别加载“import”spring-quartz.xml文件的servlet-config.xml文件,那么你将加载文件两次,这将导致你的2个实例调度。简单的解决方法是(1)确保您没有在web.xml文件中加载spring-quartz.xml或(2)删除其他xml文件中的import语句。
已更新:感谢您向我们展示了用于排除规则的web.xml。仔细检查xml文件后,您将使用作业详细信息和触发器设置SchedulerFactoryBean。这是你的问题。作业详细信息包含在触发器的一部分中,因此将它们再次放入会导致它被安排两次。请阅读有关setJobDetails()方法的这两个链接的文档:
http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/scheduling/quartz/SchedulerAccessor.html#setJobDetails%28org.quartz.JobDetail []%29
http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/scheduling/quartz/SchedulerAccessor.html#setTriggers%28org.quartz.Trigger []%29
重要信息摘录:
setJobDetails public void setJobDetails(JobDetail [] jobDetails) 使用此FactoryBean创建的Scheduler注册JobDetail对象列表,以供Triggers引用。 当Trigger确定JobDetail本身时,这不是必需的:在这种情况下,JobDetail将与Trigger一起隐式注册。
解决方案是从SchedulerFactoryBean中删除jobDetails,如下所示:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="checkAndRouteDocumentsTaskTrigger" />
</list>
</property>
</bean>