0

我有 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 配置:

    <?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...

谢谢你的帮助。

4

2 回答 2

2

您的ContextLoaderListenerDispatcherServlet都在加载mvc-dispatcher-servlet.xml. 基本上复制所有 bean 会导致 2 次执行,因为这也是重复的。

将您的配置拆分为由ContextLoaderListener(包含您的服务、dao、计时器等)加载的配置和由DispatcherServlet(仅包含与 Web 相关的 bean 控制器、视图解析器等)加载的配置。

或者ContextLoaderListener完全放弃,只使用DispatcherServlet加载所有内容。

于 2013-11-05T10:56:16.537 回答
1

确保您没有为您的项目加载 web.xml 文件中的两个文件。如果您单独加载 spring-quartz.xml 文件,然后单独加载“导入”spring-quartz.xml 文件的 servlet-config.xml 文件,那么您将加载该文件两次,这将导致您的 2 个实例调度器。简单的解决方法是(1)确保您没有在 web.xml 文件中加载 spring-quartz.xml 或(2)删除其他 xml 文件中的导入语句。

更新:感谢您向我们展示 web.xml 以排除这种情况。在仔细检查您的 xml 文件后,您将使用作业详细信息和触发器设置 SchedulerFactoryBean。这是你的问题。作业详细信息包含在您的触发器中,因此再次放入它们会导致它被安排两次。请阅读这两个链接上有关 setJobDetails() 方法的文档:

http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html

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 创建的调度程序注册一个 JobDetail 对象列表,以供触发器引用。当 Trigger 确定 JobDetail 本身时,这不是必需的:在这种情况下,JobDetail 将与 Trigger 结合隐式注册。

解决方案是从 SchedulerFactoryBean 中删除 jobDetails,如下所示:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
    <list>
        <ref bean="checkAndRouteDocumentsTaskTrigger" />
    </list>
</property>
</bean>
于 2013-11-04T22:01:17.580 回答