springboot项目定时任务纯净配置

1. 抽象实体类

@Data
public class AbstractEntity implements Serializable {

    @TableId(type = IdType.UUID)
    private String id;

    private String createBy;

    private Date createDate;

    private String updateBy;

    private Date updateDate;
}

2. 定时任务实体类

package com.len.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.len.base.AbstractEntity;
import com.len.validator.group.AddGroup;
import com.len.validator.group.UpdateGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import javax.validation.constraints.NotEmpty;
import java.util.Date;

@EqualsAndHashCode(callSuper = true)
@TableName(value = "sys_job")
@Data
@ToString
public class SysJob extends AbstractEntity {

    /**
     * 描述任务
     */
    @NotEmpty(message = "任务描述不能为空", groups = {AddGroup.class, UpdateGroup.class})
    private String jobName;

    /**
     * 任务表达式
     */
    @NotEmpty(message = "表达式不能为空", groups = {AddGroup.class, UpdateGroup.class})
    private String cron;

    /**
     * 状态:0未启动false/1启动true
     */
    private Boolean status;

    /**
     * 任务执行方法
     */
    @NotEmpty(message = "执行方法不能未空", groups = {AddGroup.class, UpdateGroup.class})
    private String clazzPath;

    /**
     * 其他描述
     */
    private String jobDesc;

}

3. 自定义JobFactory

package com.len.core.quartz;

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;
import org.springframework.stereotype.Component;

@Component
public class MyJobFactory extends AdaptableJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object job = super.createJobInstance(bundle);
        capableBeanFactory.autowireBean(job);
        return job;
    }

}

4. 自定义SchedulerFactoryBean

package com.len.core.quartz;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class MySchedulerListener {

    @Autowired
    MyJobFactory myJobFactory;

    @Bean(name = "schedulerFactoryBean")
    public SchedulerFactoryBean schedulerFactory() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setJobFactory(myJobFactory);
        bean.setConfigLocation(new ClassPathResource("quartz.properties"));
        return bean;
    }

}

5. quartz.properties

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 20
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000

org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore


6. 定时任务操作类

package com.len.core.quartz;


import com.len.entity.SysJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashSet;

/**
 * @author zhuxiaomeng
 * @date 2018/1/5.
 * @email lenospmiller@gmail.com
 *        <p>
 *        定时任务类 增删改 可参考api:http://www.quartz-scheduler.org/api/2.2.1/
 *        <p>
 *        任务名称 默认为 SysJob 类 id
 */
@Service
@Slf4j
public class JobTask {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    /**
     * true 存在 false 不存在
     *
     * @param
     * @return
     */
    public boolean checkJob(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId(), Scheduler.DEFAULT_GROUP);
        try {
            if (scheduler.checkExists(triggerKey)) {
                return true;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 开启
     */
    public boolean startJob(SysJob job) throws ClassNotFoundException, SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        Class clazz = Class.forName(job.getClazzPath());
        JobDetail jobDetail = JobBuilder.newJob(clazz).build();
        // 触发器
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId(), Scheduler.DEFAULT_GROUP);
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
            .withSchedule(CronScheduleBuilder.cronSchedule(job.getCron())).build();
        scheduler.scheduleJob(jobDetail, trigger);
        // 启动
        if (!scheduler.isShutdown()) {
            scheduler.start();
            log.info("---任务[" + triggerKey.getName() + "]启动成功-------");
            return true;
        } else {
            log.info("---任务[" + triggerKey.getName() + "]已经运行,请勿再次启动-------");
        }

        return false;
    }

    /**
     * 更新
     */
    public boolean updateJob(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        String createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");

        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId(), Scheduler.DEFAULT_GROUP);
        try {
            if (scheduler.checkExists(triggerKey)) {
                return false;
            }

            JobKey jobKey = JobKey.jobKey(job.getId(), Scheduler.DEFAULT_GROUP);

            CronScheduleBuilder schedBuilder =
                CronScheduleBuilder.cronSchedule(job.getCron()).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime)
                .withSchedule(schedBuilder).build();

            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            HashSet<Trigger> triggerSet = new HashSet<>();
            triggerSet.add(trigger);
            scheduler.scheduleJob(jobDetail, triggerSet, true);
            log.info("---任务[" + triggerKey.getName() + "]更新成功-------");
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 删除
     */
    public boolean remove(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId(), Scheduler.DEFAULT_GROUP);
        try {
            if (checkJob(job)) {
                scheduler.pauseTrigger(triggerKey);
                scheduler.unscheduleJob(triggerKey);
                scheduler.deleteJob(JobKey.jobKey(job.getId(), Scheduler.DEFAULT_GROUP));
                log.info("---任务[" + triggerKey.getName() + "]删除成功-------");
                return true;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }
}

7. 定时任务入口类

package com.len.controller;

import com.len.core.quartz.JobTask;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.len.base.BaseController;

import com.len.entity.SysJob;
import com.len.exception.ServiceException; //自定义
import com.len.service.JobService;
import com.len.util.LenResponse; //自定义
import com.len.util.MsHelper; //自定义
import com.len.util.ReType; //自定义

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @author zhuxiaomeng
 * @date 2018/1/6.
 * @email lenospmiller@gmail.com
 *        <p>
 *        定时任务 controller
 */
@Controller
@RequestMapping("/job")
@Api(value = "定时任务", tags = "定时任务")
public class JobController extends BaseController<SysJob> {


    private final JobService jobService;


    private final JobTask jobTask;

    public JobController(JobService jobService,
                         JobTask jobTask) {
        this.jobService = jobService;
        this.jobTask = jobTask;
    }

    @GetMapping(value = "showJob")
    public String showUser(Model model) {
        return "/system/job/jobList";
    }

    @GetMapping(value = "showJobList")
    @ResponseBody
    public ReType showUser(SysJob job, String page, String limit) {
        return jobService.show(job, Integer.parseInt(page), Integer.parseInt(limit));
    }

    @GetMapping(value = "showAddJob")
    public String addJob() {
        return "/system/job/add";
    }

    @ApiOperation(value = "/addJob", httpMethod = "POST", notes = "添加任务类")
    @PostMapping(value = "addJob")
    @ResponseBody
    public LenResponse addJob(SysJob job) {
        job.setStatus(false);
        jobService.save(job);
        return succ(MsHelper.getMsg("insert.success"));
    }

    @GetMapping(value = "updateJob")
    public String updateJob(String id, Model model, boolean detail) {
        if (StringUtils.isNotEmpty(id)) {
            SysJob job = jobService.getById(id);
            model.addAttribute("job", job);
        }
        model.addAttribute("detail", detail);
        return "system/job/update";
    }

    @ApiOperation(value = "/updateJob", httpMethod = "POST", notes = "更新任务")
    @PostMapping(value = "updateJob")
    @ResponseBody
    public LenResponse updateJob(SysJob job) {
        if (jobTask.checkJob(job)) {
            throw new ServiceException(MsHelper.getMsg("job.started"));
        }
        jobService.updateJob(job);
        return succ(MsHelper.getMsg("update.success"));

    }

    @ApiOperation(value = "/del", httpMethod = "POST", notes = "删除任务")
    @PostMapping(value = "del")
    @ResponseBody
    public LenResponse del(String id) {
        jobService.del(id);
        return succ(MsHelper.getMsg("del.success"));
    }

    @PostMapping(value = "startJob")
    @ResponseBody
    public LenResponse startJob(String id) {
        jobService.startJob(id);
        return succ("job.start");
    }

    @PostMapping(value = "endJob")
    @ResponseBody
    public LenResponse endJob(String id) {
        jobService.stopJob(id);
        return succ(MsHelper.getMsg("job.stop"));
    }

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值