使用spring+quartz配置多个定时任务(包括项目启动先执行一次,之后再间隔时间执行)

1.依赖

<!-- quartz -->
<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.3.0</version>
</dependency>
<!--调度器核心包-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>

需要引入的jar包, 这里是采用maven的dependency依赖; 如果没有使用maven, 可以对照着上面的jar包截图一一进行下载. 这里唯一需要注意的就是, 如果使用spring 3.1以下的版本, quartz就需要相应的2.0以下版本, 否则会导致 org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name 'cronTrigger_1' defined in file [E:workspace.metadata.pluginsorg.eclipse.wst.server.core mp0wtpwebappsgit-commonWEB-INFclassesapplicationContext.xml]: problem with class file or dependent class; nested exception isjava.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class 错误.

后续: 后来使用了spring 4.0.5.RELEASE版本+quartz 2.2.1版本, 还是报出了以上错误, 将quartz降低为1.8.6版本后, 问题消失...

2.举例代码

/**
*要定时执行的任务一
*
**/
package com.quartz.demo;  
  
import java.util.Date;  
  
public class Job1Demo {  
    public void sayHello() {  
        System.out.println(new Date() + " -> Hello, 我是任务 1");  
    }  
}  
/**
*要定时执行的任务一
*
**/
package com.quartz.demo;  
  
import java.util.Date;  
  
public class Job2Demo {  
    public void sayHello() {  
        System.out.println(new Date() + " -> Hello, 我是任务 2");  
    }  
}  

3.配置定时器applicationContext-quartz.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.1.xsd ">
    <!-- 将自定义job交给spring(将类注入Spring管理Bean) -->
    <bean name="job1" class="com.quartz.demo.Job1Demo"/> 
    <!-- 配置JobDetail -->
    <bean id="SpringQtzJobMethod_1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
     <property name="concurrent" value="false" /> <!--false表示等上一个任务执行完后再开启新的任务(默认是true) -->
        <property name="targetObject">
            <ref bean="job1" />
        </property>
        <property name="targetMethod">      <!-- 要执行的方法名称 -->
            <value>sayHello</value>         <!-- 要执行的方法名称 -->
        </property>
    </bean>
    <!-- 配置调度触发器 -->
    <bean id="cronTriggerFactoryBean_1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean ">
        <property name="jobDetail" ref="SpringQtzJobMethod_1"></property>
                <!-- 每5秒执行一次 -->
        <property name="cronExpression" value="0/5 * * * * ?"></property>
    </bean>

    <!-- 将自定义job交给spring(将类注入Spring管理Bean) -->
    <bean name="job2" class="com.quartz.demo.Job2Demo"/> 
    <!-- 配置JobDetail -->
    <bean id="SpringQtzJobMethod_2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
      <property name="concurrent" value="false" /> <!--false表示等上一个任务执行完后再开启新的任务(默认是true) -->
        <property name="targetObject">
            <ref bean="job2" />
        </property>
        <property name="targetMethod">      <!-- 要执行的方法名称 -->
            <value>sayHello</value>         <!-- 要执行的方法名称 -->
        </property>
    </bean>
    <!-- 配置调度触发器 -->
    <bean id="cronTriggerFactoryBean_2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean ">
        <property name="jobDetail" ref="SpringQtzJobMethod_2"></property>
        <!-- 每5秒执行一次 -->
        <property name="cronExpression" value="0/5 * * * * ?"></property>
    </bean>

    <!-- 项目启动就先执行一次,再按照间隔时间重复执行(SimpleTrigger)
    <bean id="simpleTriggerFactoryBean" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="SpringQtzJobMethod_2" />    
        <property name="startDelay" value="2000" />     启动延迟  单位/毫秒
        <property name="repeatInterval" value="20000" />       间隔时间 
        <property name="repeatCount" value="-1" />       重复次数(-1:无数次;0:一次.....) 
    </bean> -->
    

    <!-- 配置调度工厂 -->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 添加触发器 -->  
        <property name="triggers">
            <list>
                <ref bean="cronTriggerFactoryBean_1"/>
                <ref bean="cronTriggerFactoryBean_2"/>
               <!--  <ref bean="simpleTriggerFactoryBean"/>  -->
            </list>
        </property>
    </bean>
</beans> 

4.web.xml加载定时配置文件

<display-name>Archetype Created Web Application</display-name>  
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/applicationContext-*.xml</param-value>
    </context-param>
  
    <!-- Spring 容器启动监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  

5.时间计算cron表达式

一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。

 按顺序依次为
      1 秒(0~59)
      2 分钟(0~59)
      3 小时(0~23)
      4 天(0~31)
      5 月(0~11)
      6 星期(1~7 1为SUN-依次为SUN,MON,TUE,WED,THU,FRI,SAT)
      7.年份(1970-2099)

在线时间计算cron表达式:http://cron.qqe2.com/

6.作者实际运用在项目中遇到的问题:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 异常

 解决方法:

  这个是因为spring容器里面有两个类型一样的bean,但是spring不知道加载哪一个,需要你手动指定一个默认的加载(会优先加载@Primary注解的类型) 用@Primary在标识在Class上面 。

参考文章:

  https://www.jianshu.com/p/d0edb298e891

  https://www.cnblogs.com/qlqwjy/p/8721963.html

原文地址:https://www.cnblogs.com/Moming0/p/11850760.html