动态Quart定时任务 项目目录:

file

Sql文件:


创建表:

CREATE TABLE `sys_task` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL COMMENT '任务名',
  `content` varchar(50) DEFAULT NULL COMMENT '任务描述',
  `cron_expression` varchar(30) NOT NULL COMMENT '七子表达式',
  `class_method` varchar(200) NOT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',
  `state` varchar(1) NOT NULL COMMENT '任务状态 0:未启动 1:启动',
  `job_group` varchar(20) NOT NULL COMMENT '分组+名字会生成一个job任务 两者+相加不能重复!!!',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=36 DEFAULT CHARSET=utf8;

插入测试数据:
INSERT INTO `cnbuilder`.`sys_task` ( `id`, `name`, `content`, `cron_expression`, `class_method`, `state`, `job_group`, `create_time`, `update_time` )
VALUES
	( 1, 'helloword', '测试', '0/10 * * * * ?', 'cn.cnbuilder.trendsquartz.task.HelloWorldJob', '0', 'TEST_GROUP', '2018-06-29 23:31:42', '2018-06-29 23:31:42' );

java代码


config:
package cn.cnbuilder.trendsquartz.config;


import cn.cnbuilder.trendsquartz.factory.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;
import java.util.Properties;

import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
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 QuartzConfig {

    @Autowired
    private JobFactory jobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        try {
            //覆盖原来的任务
            schedulerFactoryBean.setOverwriteExistingJobs(true);
            //容器工厂
            schedulerFactoryBean.setJobFactory(jobFactory);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return schedulerFactoryBean;
    }

    // 创建schedule
    @Bean(name = "scheduler")
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }
}


JobFactory:

package cn.cnbuilder.trendsquartz.factory;

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 JobFactory extends AdaptableJobFactory {
    //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
    //为什么需要这个类呢,在我写的这个demo中,大家可以将此类删掉,发现程序也可以政策运营,可是我为什么还是加上呢。
    //大家可以看下我们的任务类,大家可以看到Job对象的实例化过程是在Quartz中进行的,这时候我们将spring的东西注入进来,肯定是行不通的,所以需要这个类
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}


ScheduleJobInitListener:

package cn.cnbuilder.trendsquartz.listenner;


 import cn.cnbuilder.trendsquartz.service.ScheduleJobService;
 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(value = 1)
public class ScheduleJobInitListener implements CommandLineRunner {

    @Autowired
    ScheduleJobService scheduleJobService;

    @Override
    public void run(String... arg0) throws Exception {
        try {
            //初始化
            scheduleJobService.initSchedule();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}


ScheduleJobService:

package cn.cnbuilder.trendsquartz.service;


import org.quartz.SchedulerException;

import java.util.List;


/**
 * 初始化定时任务工作
 */
public interface ScheduleJobService {
    void initSchedule() throws SchedulerException;
}
ScheduleJobServiceImpl:
package cn.cnbuilder.trendsquartz.service.impl;

import cn.cnbuilder.trendsquartz.enums.JobStatusEnum;
import cn.cnbuilder.trendsquartz.mapper.JobsMapper;
import cn.cnbuilder.trendsquartz.service.ScheduleJobService;
import cn.cnbuilder.trendsquartz.utils.QuartzManager;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class ScheduleJobServiceImpl implements ScheduleJobService {
    @Autowired
    private JobsMapper jobsMapper;

    @Autowired
    QuartzManager quartzManager;

    @Override
    public void initSchedule() throws SchedulerException {
        // 这里获取任务信息数据
        List<Map> jobList = jobsMapper.list();
        for (Map map : jobList) {
            if (JobStatusEnum.RUNNING.getCode().equals(map.get("state"))) {
                quartzManager.addJob(map);
            }
        }
    }
}

JobsController:
package cn.cnbuilder.trendsquartz.controller;


import cn.cnbuilder.trendsquartz.enums.JobStatusEnum;


import cn.cnbuilder.trendsquartz.service.JobsService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * quartz 控制层
 */
@Controller
@RequestMapping("/job")
public class JobsController {
    @Autowired
    private JobsService jobsService;


    @ResponseBody
    @PostMapping("/slectAll")
    public List<Map> slectAll() {
        // 查询列表数据
        List<Map> result = jobsService.list();
        return result;
    }


    @PostMapping("/edit")
    @ResponseBody
    public String edit(
            String name,
            String content,
            String cron_expression,
            String class_method,
            String job_group,
            Long id
    ) {
        Map job = jobsService.get(id);
        if (JobStatusEnum.RUNNING.getCode().equals(job.get("state"))) {
            return "修改之前请先停止任务!";
        }
        jobsService.updateJob(name, content, cron_expression, class_method, job_group, id, job.get("state").toString());

        return "success";
    }


    @PostMapping("/changeStatus/{id}")
    @ResponseBody
    public String changeStatus(@PathVariable("id") Long id, Boolean jobStatus) {
        String status = jobStatus == true ? JobStatusEnum.RUNNING.getCode() : JobStatusEnum.STOP.getCode();
        try {
            jobsService.changeStatus(id, status);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "任务状态修改失败";
    }

    /**
     * 删除
     */
    @PostMapping("/remove/{id}")
    @ResponseBody
    public String remove(@PathVariable("id") Long id) {
        Map taskServer = jobsService.get(id);
        if (JobStatusEnum.RUNNING.getCode().equals(taskServer.get("state").toString())) {
            return "删除前请先停止任务!";

        }
        if (jobsService.remove(id) > 0) {
            return "success";
        }
        return "删除任务失败! ";
    }

    /**
     * 批量删除
     */
    @PostMapping("/removeBatch")
    @ResponseBody
    public String removeBatch(@RequestParam("ids[]") Long[] ids) {
        for (Long id : ids) {
            Map taskServer = jobsService.get(id);
            if (JobStatusEnum.RUNNING.getCode().equals(taskServer.get("state").toString())) {
                return "删除前请先停止任务!";
            }
        }
        jobsService.removeBatch(ids);
        return "success";
    }

    /**
     * 新增保存
     */
    @ResponseBody
    @PostMapping("/save")
    public String save(
            String name,
            String content,
            String cron_expression,
            String class_method,
            String job_group
    ) {
        if (jobsService.save(name, content, cron_expression, class_method, job_group) > 0) {
            return "success";
        }
        return "新增任务失败!";
    }


}

jobService:

package cn.cnbuilder.trendsquartz.service;

import org.quartz.SchedulerException;

import java.util.List;
import java.util.Map;


/**
 * JobsService
 */
public interface JobsService {

    Map get(Long id);

    List<Map> list();

    int save(String name, String content, String cron_expression, String class_method, String group);

    int updateJob(String name, String content, String cron_expression, String class_method, String job_group, Long id, String state);

    int remove(Long id);

    int removeBatch(Long[] ids);


    void changeStatus(Long jobId, String jobStatus) throws SchedulerException;

    void updateCron(Long jobId) throws SchedulerException;

}

JobsServiceImpl:
package cn.cnbuilder.trendsquartz.service.impl;

import cn.cnbuilder.trendsquartz.enums.JobStatusEnum;
import cn.cnbuilder.trendsquartz.mapper.JobsMapper;

import cn.cnbuilder.trendsquartz.service.JobsService;
import cn.cnbuilder.trendsquartz.utils.QuartzManager;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


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

@Service
public class JobsServiceImpl implements JobsService {
    @Autowired
    private JobsMapper jobsMapper;

    @Autowired
    QuartzManager quartzManager;

    @Override
    public Map get(Long id) {
        return jobsMapper.get(id);
    }

    @Override
    public List<Map> list() {
        List<Map> list = jobsMapper.list();
        return list;
    }

    @Override
    public int save(String name, String content, String cron_expression, String class_method, String job_group) {

        //进行封装包装
        HashMap<String, Object> job = new HashMap<>();
        job.put("name", name);
        job.put("content", content);
        job.put("cron_expression", cron_expression);
        job.put("class_method", class_method);
        job.put("job_group", job_group);
        job.put("create_time", new Date());
        job.put("update_time", new Date());
        //默认关闭定时任务
        job.put("state", 0);
        return jobsMapper.save(job);
    }

    @Override
    public int updateJob(String name, String content, String cron_expression, String class_method, String job_group, Long id, String state) {
        HashMap<String, Object> job = new HashMap<>();
        job.put("name", name);
        job.put("content", content);
        job.put("cron_expression", cron_expression);
        job.put("class_method", class_method);
        job.put("job_group", job_group);
        job.put("update_time", new Date());
        job.put("id", id);
        job.put("state", state);
        return jobsMapper.update(job);
    }

    @Override
    public int remove(Long id) {
        try {
            Map job = get(id);
            quartzManager.deleteJob(job);
            return jobsMapper.remove(id);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return 0;
        }

    }

    @Override
    public int removeBatch(Long[] ids) {
        for (Long id : ids) {
            try {
                Map task = get(id);
                quartzManager.deleteJob(task);
            } catch (SchedulerException e) {
                e.printStackTrace();
                return 0;
            }
        }
        return jobsMapper.removeBatch(ids);
    }


    @Override
    public void changeStatus(Long jobId, String jobStatus) throws SchedulerException {
        Map job = get(jobId);
        if (job == null) {
            return;
        }
        if (JobStatusEnum.STOP.getCode().equals(jobStatus)) {
            //暂停job
            quartzManager.deleteJob(job);
            job.put("state", 0);
        } else {
            job.put("state", 1);
            //直接启动
            quartzManager.addJob(job);
        }
        updateJob(job.get("name").toString(), job.get("content").toString(), job.get("cron_expression").toString(), job.get("class_method").toString(), job.get("job_group").toString(), jobId, job.get("state").toString());

    }

    @Override
    public void updateCron(Long jobId) throws SchedulerException {
        Map job = get(jobId);
        if (job == null) {
            return;
        }
        if (JobStatusEnum.RUNNING.getCode().equals(job.get("state").toString())) {
            quartzManager.updateJobCron(job);
        }
        updateJob(job.get("name").toString(), job.get("content").toString(), job.get("cron_expression").toString(), job.get("class_method").toString(), job.get("job_group").toString(), jobId, job.get("state").toString());
    }
}

JobsMapper:

package cn.cnbuilder.trendsquartz.mapper;


import org.apache.ibatis.annotations.Mapper;


import java.util.List;
import java.util.Map;

@Mapper
public interface JobsMapper {
    Map get(Long id);

    List<Map> list();

    int save(Map job);

    int update(Map task);

    int remove(Long id);

    int removeBatch(Long[] ids);
}

QuartzMapper.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.cnbuilder.trendsquartz.mapper.JobsMapper">

	<select id="get" parameterType="java.lang.Long" resultType="map">
		select
	      id, name, content, cron_expression, class_method, state,
        job_group, create_time, update_time
		from sys_task
		where id = #{id,jdbcType=BIGINT}
	</select>
	<select id="list" resultType="map">
		select
	      id, name, content, cron_expression, class_method, state,
        job_group, create_time, update_time
		from sys_task
		order by id asc
	</select>

	<insert id="save" parameterType="map">
        insert into sys_task (id, name, content, cron_expression, class_method, state,
        job_group, create_time, update_time)
        values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR},
        #{content,jdbcType=VARCHAR},
        #{cron_expression,jdbcType=VARCHAR}, #{class_method,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR},
        #{job_group,jdbcType=VARCHAR},
        #{create_time,jdbcType=TIMESTAMP},
        #{update_time,jdbcType=TIMESTAMP})
    </insert>

	<update id="update" parameterType="map">
		update sys_task
		<set>
			<if test="name != null">
				name = #{name,jdbcType=VARCHAR},
			</if>
			<if test="content != null">
				content = #{content,jdbcType=VARCHAR},
			</if>
			<if test="cronExpression != null">
				cron_expression = #{cron_expression,jdbcType=VARCHAR},
			</if>
			<if test="class_method != null">
				class_method = #{class_method,jdbcType=VARCHAR},
			</if>
			<if test="state != null">
				state = #{state,jdbcType=VARCHAR},
			</if>
			<if test="job_group != null">
				job_group = #{job_group,jdbcType=VARCHAR},
			</if>

			<if test="createTime != null">
				create_time = #{create_time,jdbcType=TIMESTAMP},
			</if>

			<if test="updateTime != null">
				update_time = #{update_time,jdbcType=TIMESTAMP},
			</if>
		</set>
		where id = #{id,jdbcType=BIGINT}
	</update>

	<delete id="remove">
        delete from sys_task where id = #{id,jdbcType=BIGINT}
    </delete>

	<delete id="removeBatch">
		delete from sys_task where id in
		<foreach item="id" collection="array" open="(" separator=","
				 close=")">
			#{id}
		</foreach>
	</delete>

</mapper>


application.yml:

spring:
  profiles:
    active: dev #选择要用那个配置文件
	
application-dev.yml:

#项目端口号访问路径
server:
  port: 12001
  servlet:
    context-path: /

#spring
spring:
  # mysql 配置
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:mysql://127.0.0.1/cnbuilder?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root

#mybatis
mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: cn.cnbuilder.trendsquartz.entity
  global-config:
    # 数据库相关配置
    db-config:
      #主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: id_worker
      #字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
      field-strategy: not_empty
      #驼峰下划线转换
      column-underline: true
      #数据库大写下划线转换
#      capital-mode: true
      #逻辑删除配置
      logic-delete-value: 0
      logic-not-delete-value: 1
    #刷新mapper 调试神器
    refresh: true
  # 原生配置
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
		
TrendsquartzApplication:

package cn.cnbuilder.trendsquartz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootAppTrendsquartzApplicationlication
public class TrendsquartzApplication {
    public static void main(String[] args) {
        SpringApplication.run(TrendsquartzApplication.class, args);
    }

}

HelloWorldJob:

package cn.cnbuilder.trendsquartz.task;


import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;

import java.util.Date;

@DisallowConcurrentExecution //作业不并发
@Component
public class HelloWorldJob implements Job {
    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("欢迎使用定时任务 "+ new Date());
    }
}


pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.cnbuilder</groupId>
    <artifactId>trendsquartz</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>trendsquartz</name>
    <description>SpringBoot动态quartzDemo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- quartz -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

终、、本文就是Springboot整合动态Quartz,有什么问题可以联系我。


本文用到的代码下载链接: https://pan.baidu.com/s/1597HW2OZNM2hS8YV2-IsOA 提取码: 62zq

鼓励作者写出更好的技术文档,就请我喝一瓶哇哈哈哈哈哈哈哈。。你们的赞助决定我更新的速度哦!

微信:

支付宝:


感谢一路支持我的人。。。。。

Love me and hold me
QQ:69673804(16年老号)
EMAIL:itw@tom.com
友链交换
如果有兴趣和本博客交换友链的话,请按照下面的格式在评论区进行评论,我会尽快添加上你的链接。

网站名称:猿码优创
网站地址:http://blog.cnbuilder.cn
网站描述:年少是你未醒的梦话,风华是燃烬的彼岸花。
网站Logo/头像: [头像地址](https://blog.cnbuilder.cn/upload/2018/7/avatar20180720144536200.jpg)

欢迎关注猿码优创(联系小优优进内部群哦,新鲜技术优先更新):

file