• Spring和Quartz整合实现定时任务调度


    在Spring中可以很方便的使用Quartz来实现定时任务等功能,Quartz主要就是Schedule(任务调度器),Job(作业任务)和Trigger(触发器)三者的关系。

    实现方式有多种,在此就介绍两种:

    第一种:Job 继承 QuartzJobBean

    1.实体

    package com.wfcm.quartz;
    
    import com.wfcm.service.WfCollageOrderService;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    import org.springframework.stereotype.Component;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @Component
    public class CollageOrderStatus extends QuartzJobBean {
    
        @Autowired
        private WfCollageOrderService collageOrderService;
    
        private org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(CollageOrderStatus.class);
    
        protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    
            log.info("团购订单状态更新任务开始..." + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            this.collageOrderService.updateStatus();
            log.info("团购订单状态更新成功!" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        }
    
        public void setCollageOrderService(WfCollageOrderService collageOrderService) {
            this.collageOrderService = collageOrderService;
        }
    
    }
    View Code

    2.配置 applicationContext-quartz.xml

       <!--JobDetail  每1分钟自动更新团购订单时间大于3分钟的订单状态为过期-->
        <bean name="collageOrderJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
            <property name="jobClass" value="com.wfcm.quartz.CollageOrderStatus"/>
            <property name="jobDataMap">
                <map>
                    <entry key="collageOrderService" value-ref="wfCollageOrderService"/>
                </map>
            </property>
            <property name="durability" value="true"/>
        </bean>
    
        <!--trigger-->
        <bean id="collageOrderJobCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="jobDetail" ref="collageOrderJob"/>
            <property name="cronExpression" value="*/2 * * * * ?"/>
            <!--<property name="cronExpression" value="0 */1 * * * ?"/>-->
        </bean>
    
        <!-- 调度器工厂bean,将作业细节和触发器粘合在一起,以配置Quartz调度器 -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="jobDetails">
                <list>
                    <ref bean="collageOrderJob"/>
                </list>
            </property>
    
            <property name="triggers">
                <list>
                    <ref bean="collageOrderJobCronTrigger"/>
                </list>
            </property>
        </bean>

    3.引用xml

        <!-- 引入定时器 -->
        <import resource="classpath:applicationContext-quartz.xml"/>

    第二种:

    1. 普通java类

    package com.wfcm.quartz;
    
    import com.mysql.jdbc.TimeUtil;import com.wfcm.utils.DateUtil;
    import com.wfcm.utils.DateUtils;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    import org.springframework.stereotype.Component;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @Component
    public class RemindTask {
    
        private Logger log = LoggerFactory.getLogger(RemindTask.class);
    
        public void start(){
            System.out.println(DateUtil.format(new Date(),DateUtils.DATE_TIME_PATTERN));
        }
    
    }

    2.xml 配置

     <!-- job -->
        <bean id="remindTask" class="com.wfcm.quartz.RemindTask"/>
        <!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
        <!-- jobDetail -->
        <bean id="remindTaskJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <!--<property name="targetObject" ref="com.wfcm.quartz.RemindTask"/>
            <property name="targetMethod" value="start"/>-->
            <!--false表示等上一个任务执行完后再开启新的任务-->
            <!--<property name="concurrent" value="false"/>-->
            <property name="targetObject">
                <ref bean="remindTask"></ref>
            </property>
            <property name="targetMethod">
                <value>start</value>
            </property>
        </bean>
        <!-- Trigger-->
        <bean id="remindTaskCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="jobDetail" ref="remindTaskJob"/>
            <property name="cronExpression">
                <value>0/1 * * * * ?</value>
            </property>
            <!--<property name="startDelay" value="1"/>-->
            <!--<property name="cronExpression" value="0 */2 * * * ?"/>-->
        </bean>
        <!--Scheduler -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="remindTaskCronTrigger"/>
                </list>
            </property>
        </bean>

    3.引用 xml ,和第一种方式一样。

    接下来就是测试了,定时任务用哪种方式都可以。

    回想一下之前说过的Quartz三个要素:Scheduler、Trigger、JobDetai&Job。对应到xml文件,也就是上面的中的几个bean对象。几个点注意下:

    一个scheduler可以对应多个Trigger:看bean对象也看出来了,它的属性是个list集合。

    一个job可以对应多个JobDetail:这个其实也好理解,毕竟具体的实现是job实现,但是通过jobDetail去管理job。就好比游戏和外挂,总不能你同一个游戏开两个客户端,你还买2个挂吧?外挂相当于管理游戏的也就是JobDetail,而游戏相等于具体的实现Job。

    job可以自己指定方法名: 之前job都是通过实现job接口,实现execute方法。现在只需要通过jobDetai的属性targetMethod指定执行方法,但是需要注意这个jobDetail它是使用MethodInvokingJobDetailFactoryBean作为具体实现。

    具体的体系结构从网上copy过来,讲的比较详细:
    ●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。
    
    ●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。
    
    ●Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等。
    
    ●Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。

    时间计算:cron  ,可以去这个网站  在线Cron表达式生成http://cron.qqe2.com/

  • 相关阅读:
    双色球随机一注
    if else的简写
    select
    预解析
    json
    数组方法
    arguments
    国密SM4算法
    AES算法
    Feistel算法结构与DES加密算法
  • 原文地址:https://www.cnblogs.com/hero123/p/10863264.html
Copyright © 2020-2023  润新知