java学习心得——Quartz 自定义定时器的操作

2021-01-16 07:15

阅读:494

标签:判断   tab   pac   int   自己的   eject   实体   fast   task   

最近在邮件提醒的业务里,需要根据后台每个项目的配置定时的向项目联系人推送邮件提醒,这时我明白需要定时任务了,作为java小白,我向同事做了咨询,推荐我使用Quartz,以下便是我在项目里的学习心得。

首先配置文件:

依赖的jar包

        org.quartz-scheduler
            quartz
            1.8.0org.springframework
            spring-context-support
            3.2.17.RELEASE

配置文件:

class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        class="java.util.concurrent.ThreadPoolExecutor$AbortPolicy"/>
        class="com.imaster.admin.web.schemajob.QuartzManager">
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
         

        class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
         
           class="com.imaster.admin.web.schemajob.JobAdapter">

 

quartzManager定义自己的的定时器管理类
1.读取数据库的定时任务的设置数据
2.添加新的定时任务
3.删除已取消的定时任务
4.更新已有的定时任务

技术图片技术图片
package com.imaster.admin.web.schemajob;

import com.imaster.admin.model.vo.TaskVo;
import com.imaster.admin.shared.service.version2.ExhibitorReserveExhibitionService;
import com.imaster.constant.ApplicationConfig;
import com.imaster.shared.enums.TaskTypeEnum;
import com.imaster.shared.model.ExhibitorReserveExhibition;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.CronTriggerBean;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author wanghh
 * 2020/5/9 11:45
 */
public class QuartzManager implements BeanFactoryAware {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(ApplicationConfig.SERVER_NAME);

    private Scheduler scheduler;

    private static BeanFactory beanFactory;
    @Autowired
    ExhibitorReserveExhibitionService reserveExhibitionService;


    /**
     * 定时要执行的方法类。
     */
    public void reScheduleJob() {
        // 1.读取数据库中的任务列表。

        //获取短信定时任务
        List list = reserveExhibitionService.selectList(null);
        for (ExhibitorReserveExhibition item : list
        ) {
            TaskVo taskVo = new TaskVo();
            taskVo.setTaskId(item.getId());
            taskVo.setTaskType(TaskTypeEnum.EXHIBITOR_RESERVE.getCode());
            taskVo.setCronExpression(String.format("0 %s %s * * ? ",item.getAcceptEmailMinute(),item.getAcceptEmailHour()));
            if (item.getDeleted() == 1 || item.getEnabled() == 0||item.getAcceptEmailRuleTime()==0) {
                //去掉过时的任务
                removeExpireTasks(taskVo);
            } else {
                configSchedul(taskVo);
            }
        }
    }

    /**
     * 移除过期任务
     *
     * @param bo
     */
    private void removeExpireTasks(TaskVo bo) {
        try {
            CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(bo.getTaskId() + "name" + bo.getTaskType(), Scheduler.DEFAULT_GROUP);
            if (trigger != null) {
                logger.info("==移除任务==" + bo.getTaskId() + "name" + bo.getTaskType());
                scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());// 停止触发器
                scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());// 移除触发器
                scheduler.deleteJob(trigger.getJobName(), trigger.getJobGroup());// 删除任务
            }
        } catch (SchedulerException e) {
            logger.error("移除任务失败...");
            e.printStackTrace();
        }
    }

    /**
     * 配置任务列表
     *
     * @param bo
     */
    private void configSchedul(TaskVo bo) {
        try {
            CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(bo.getTaskId() + "name" + bo.getTaskType(), Scheduler.DEFAULT_GROUP);
            if (trigger == null) {//说明schedule中不存在该定时任务
                createTriggerTask(bo);
            } else {
                updateTriggerTask(bo, trigger);
            }
        } catch (SchedulerException e) {
            logger.error("获取触发器trigger失败...");
            e.printStackTrace();
        }
    }


    /**
     * 更新任务列表
     *
     * @param bo
     */
    private void updateTriggerTask(TaskVo bo, CronTriggerBean trigger) {

        try {
            // 判断从DB中取得的任务时间和现在的quartz线程中的任务时间是否相等
            // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob
            if (trigger.getCronExpression() != null &&
                    !trigger.getCronExpression().equalsIgnoreCase(bo.getCronExpression())) {
                logger.info("=真正更新方法:=" + bo.getTaskId() + "name" + bo.getTaskType());
                trigger.setCronExpression(bo.getCronExpression());
                scheduler.rescheduleJob(bo.getTaskId() + "name" + bo.getTaskType(), Scheduler.DEFAULT_GROUP, trigger);
                logger.info("更新任务时间失败...");
            }
        } catch (Exception e) {
            logger.error("更新任务时间失败...");
            e.printStackTrace();
        }
    }



    /**
     * 创建任务列表
     *
     * @param bo
     */
    private void createTriggerTask(TaskVo bo) {

        logger.info("=创建:=" + bo.getTaskId() + "name" + bo.getTaskType());

        try {
            Class clazz = QuartzJobFactory.class;//执行计划任务的类
            JobDetail jobDetail = new JobDetail(bo.getTaskId() + "", clazz);
            Map map = new HashMap();
            map.put("task", bo);
            jobDetail.setJobDataMap(new JobDataMap(map));
            jobDetail.setName(bo.getTaskId() + "name" + bo.getTaskType());
            scheduler.addJob(jobDetail, true); // 将Job添加到管理类

            // 新一个基于Spring的时间类
            CronTriggerBean c = new CronTriggerBean();
            c.setCronExpression(bo.getCronExpression());// 设置时间表达式
            c.setName(bo.getTaskId() + "name" + bo.getTaskType());// 设置名称
            c.setJobDetail(jobDetail);// 注入Job
            c.setJobName(bo.getTaskId() + "name" + bo.getTaskType());// 设置Job名称
            scheduler.scheduleJob(c);// 注入到管理类
            scheduler.rescheduleJob(bo.getTaskId() + "name" + bo.getTaskType(), Scheduler.DEFAULT_GROUP, c);// 刷新管理类
        } catch (Exception e) {
            logger.error("创建" + bo.getTaskId() + "name" + bo.getTaskType() + "任务失败...");
            e.printStackTrace();
        }
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        QuartzManager.beanFactory = beanFactory;

    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    public QuartzManager setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
        return this;
    }

    public static BeanFactory getBeanFactory() {
        return beanFactory;
    }
}
QuartzManager
QuartzJobFactory 定义了具体定时任务的执行管理
所有的定时任务都会在时间点执行这个类的execute(),然后我们根据定时任务的TaskType来确定具体的任务,另外注意我这边是直接将我的参数作为taskId了,所有我传入的参数是taskId,如果可以根据自己的业务需要在TaskVO中补充自己的参数
技术图片技术图片
package com.imaster.admin.web.schemajob;

import com.alibaba.fastjson.JSON;
import com.imaster.admin.model.vo.TaskVo;
import com.imaster.admin.web.biz.ExhibitorReserveBiz;
import com.imaster.constant.ApplicationConfig;
import com.imaster.shared.enums.TaskTypeEnum;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author wanghh
 * 2020/5/9 12:07
 */
public class QuartzJobFactory implements Job {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(ApplicationConfig.SERVER_NAME);

    @Autowired
    private ExhibitorReserveBiz exhibitorReserveBiz;


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        TaskVo taskVo = (TaskVo) jobDataMap.get("task");
        logger.info("定时任务开始执行。。。。。。。。。。。" + JSON.toJSONString(taskVo));
        if (TaskTypeEnum.EXHIBITOR_RESERVE.getCode().equals(taskVo.getTaskType())) {
            logger.info("zhangshangbaoming job=======" + taskVo.getTaskId());
             exhibitorReserveBiz.sendAcceptTimeEmail(taskVo.getTaskId());
            //msgSendSchemaService.sendSchemaMsg(taskVo.getTaskId());
        }

    }
}
QuartzJobFactory
JobAdapter 这个类其实我没有明白,只能邯郸学步,请见谅,看别人的注释吧。
package com.imaster.admin.web.schemajob;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;

/**
 * @Author wanghh
 * 2020/5/11 10:17
 */
public class JobAdapter extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
TaskVo 实体类
技术图片技术图片
package com.imaster.admin.model.vo;

import lombok.Data;

/**
 * @Author wanghh
 * 2020/5/9 11:50
 */
@Data
public class TaskVo {
    public String taskId;

    public String taskType;

    public String cronExpression;

    public String state;
}
TaskVo

 

以上就是我本次需求的处理,说实话,我只是在照葫芦画瓢,以后的项目之余我会逐步的去补充。

另外我和原创都是单台的服务器,所以没有考虑到集群的情况下。

原创地址:https://www.cnblogs.com/likun10579/p/10896831.html

谢谢挖坑大王的分享。@挖坑大王

 

java学习心得——Quartz 自定义定时器的操作

标签:判断   tab   pac   int   自己的   eject   实体   fast   task   

原文地址:https://www.cnblogs.com/qzzy/p/12926439.html


评论


亲,登录后才可以留言!