前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springBoot动态整合Quartz

springBoot动态整合Quartz

作者头像
猿码优创
发布2020-02-13 23:30:21
6570
发布2020-02-13 23:30:21
举报
文章被收录于专栏:猿码优创猿码优创

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

file
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档