玩转 Spring Boot 集成篇(任务动态管理代码篇)
Posted 一猿小讲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玩转 Spring Boot 集成篇(任务动态管理代码篇)相关的知识,希望对你有一定的参考价值。
* 定时任务管理**/
@ private TaskInfoService taskInfoService;
@ public Result list(@RequestBody TaskInfoReq reqVo)
@ public Result edit(@RequestBody TaskInfoReq reqVo)
@ public Result pause(Integer taskId)
@ public Result add(@RequestBody TaskInfoReq taskInfoReq)
@ public Result resume(Integer taskId)
@ public Result delete(@RequestBody TaskInfoReq reqVo)
com.example.demo.quartz.task;
com.example.demo.quartz.entity.TaskInfo;
com.example.demo.quartz.utils.SpringContextUtils;
com.example.demo.quartz.vo.TaskInfoReq;
org.quartz.*;
org.slf4j.Logger;
org.slf4j.LoggerFactory;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Component;
* 任务管理
* 1、添加任务 2、更新任务 3、暂停任务 4、恢复任务
**/
Logger LOGGER = LoggerFactory.getLogger(TaskManager.class);
String JOB_DEFAULT_GROUP_NAME = String TRIGGER_DEFAULT_GROUP_NAME = Scheduler scheduler;
SpringContextUtils springContextUtils;
* 添加任务
*/
flag = (!CronExpression.isValidExpression(taskInfoReq.getCron()))
LOGGER.error(
String className = springContextUtils.getBean(taskInfoReq.getJobName()).getClass().getName();
JobDetail jobDetail = JobBuilder.newJob().withIdentity(JobKey(taskInfoReq.getJobName(), JOB_DEFAULT_GROUP_NAME))
.ofType((Class<Job>) Class.forName(className))
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(taskInfoReq.getCron()))
.withIdentity(TriggerKey(taskInfoReq.getJobName(), TRIGGER_DEFAULT_GROUP_NAME))
.build();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
(Exception e)
LOGGER.error( flag =
flag;
* 更新任务
*/
flag =
JobKey jobKey = JobKey(taskInfo.getJobName(), JOB_DEFAULT_GROUP_NAME);
TriggerKey triggerKey = TriggerKey(taskInfo.getJobName(), TRIGGER_DEFAULT_GROUP_NAME);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
(scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey))
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(taskInfo.getCron()))
.withIdentity(triggerKey)
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
LOGGER.info(
LOGGER.info( (SchedulerException e)
LOGGER.error( flag =
flag;
* 暂停任务
*/
scheduler.pauseJob(JobKey.jobKey(taskInfo.getJobName(), JOB_DEFAULT_GROUP_NAME));
LOGGER.info( (SchedulerException e)
LOGGER.error(
* 恢复任务
*/
scheduler.resumeJob(JobKey.jobKey(taskInfo.getJobName(), JOB_DEFAULT_GROUP_NAME));
LOGGER.info( (SchedulerException e)
LOGGER.error(
com.example.demo.quartz.common.EnumTaskEnable;
com.example.demo.quartz.entity.TaskInfo;
com.example.demo.quartz.service.TaskInfoService;
com.example.demo.quartz.vo.TaskInfoReq;
org.quartz.Scheduler;
org.quartz.SchedulerException;
org.slf4j.Logger;
org.slf4j.LoggerFactory;
org.springframework.beans.BeanUtils;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Component;
org.springframework.util.StringUtils;
javax.annotation.PostConstruct;
java.util.List;
logger = @ scheduler;
@ springJobFactory;
@ taskInfoService;
@ void start()
scheduler.setJobFactory(springJobFactory);
(taskInfo : tasks)
( data=new taskInfoService.addJob(data);
logger.info( (e)
logger.error(e.getMessage(), e);
new
com.example.demo.quartz.config;
org.quartz.spi.TriggerFiredBundle;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.beans.factory.config.AutowireCapableBeanFactory;
org.springframework.scheduling.quartz.AdaptableJobFactory;
org.springframework.stereotype.Component;
* 解决spring bean注入Job的问题
*/
AutowireCapableBeanFactory capableBeanFactory;
Object Exception
Object jobInstance = capableBeanFactory.autowireBean(jobInstance);
jobInstance;
(
AUTO_INCREMENT datetime datetime PRIMARY (AUTO_INCREMENT=lombok.Data;
java.io.Serializable;
java.util.Date;
TaskInfo Serializable
Integer id;
cron;
jobName;
status;
createTime;
updateTime;
com.example.demo.quartz.common.Result;
com.example.demo.quartz.entity.TaskInfo;
com.example.demo.quartz.vo.TaskInfoReq;
java.util.List;
* 定时任务接口
**/
interface TaskInfoService
List<TaskInfo> selectTasks();
com.example.demo.quartz.service.impl;
com.example.demo.quartz.common.CodeMsg;
com.example.demo.quartz.common.EnumTaskEnable;
com.example.demo.quartz.common.ResponseFactory;
com.example.demo.quartz.common.Result;
com.example.demo.quartz.dao.TaskInfoDao;
com.example.demo.quartz.entity.TaskInfo;
com.example.demo.quartz.service.TaskInfoService;
com.example.demo.quartz.task.TaskManager;
com.example.demo.quartz.vo.TaskInfoReq;
com.github.pagehelper.PageHelper;
com.github.pagehelper.PageInfo;
org.quartz.CronExpression;
org.slf4j.Logger;
org.slf4j.LoggerFactory;
org.springframework.beans.BeanUtils;
org.springframework.stereotype.Service;
org.springframework.transaction.javax.java.util.Date;
java.util.List;
java.util.Objects;
* 定时任务业务实现
**/
static Logger LOGGER = LoggerFactory.getLogger(TaskInfoServiceImpl. TaskInfoDao taskInfoDao;
TaskManager taskManager;
Result selectTaskListByPage(TaskInfoReq taskInfoReq)
PageHelper.startPage(taskInfoReq.getPageCurrent(), taskInfoReq.getPageSize());
List<TaskInfo> list = taskInfoDao.selectTaskInfos(taskInfoReq);
PageInfo<TaskInfo> pageInfo = new PageInfo<>(list);
ResponseFactory.build(pageInfo);
Result updateJob(TaskInfoReq taskInfoReq)
(!CronExpression.isValidExpression(taskInfoReq.getCron()))
LOGGER.error( ResponseFactory.build(CodeMsg.TASK_CRON_ERROR);
TaskInfo isExistData = taskInfoDao.selectByJobName(taskInfoReq.getJobName());
((!Objects.isNull(isExistData)) && (!isExistData.getId().equals(taskInfoReq.getId())))
ResponseFactory.build(CodeMsg.TASK_CRON_DOUBLE);
TaskInfo = taskInfoDao.selectByPrimaryKey(taskInfoReq.getId());
(== ResponseFactory.build(CodeMsg.TASK_NOT_EXITES);
BeanUtils.copyProperties(taskInfoReq, taskInfoDao.updateByPrimaryKeySelective( (!taskManager.updateJob( ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
ResponseFactory.build();
Result pauseJob(Integer taskId)
TaskInfo = taskInfoDao.selectByPrimaryKey(taskId);
(== ResponseFactory.build(CodeMsg.TASK_NOT_EXITES);
(!taskManager.pauseJob( ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
taskInfoDao.updateByPrimaryKeySelective( ResponseFactory.build();
Result resumeJob(Integer taskId)
TaskInfo = taskInfoDao.selectByPrimaryKey(taskId);
(== ResponseFactory.build(CodeMsg.TASK_NOT_EXITES);
(!taskManager.resumeJob( ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
taskInfoDao.updateByPrimaryKeySelective( ResponseFactory.build();
Result addJob(TaskInfoReq taskInfoReq)
(!taskManager.addJob(taskInfoReq))
ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
TaskInfo = taskInfoDao.selectByJobName(taskInfoReq.getJobName());
(Objects.isNull( = new TaskInfo();
BeanUtils.copyProperties(taskInfoReq, taskInfoDao.insertSelective( ResponseFactory.build();
ResponseFactory.build(CodeMsg.TASK_CRON_DOUBLE);
Result delete(TaskInfoReq reqVo)
Result result = (CodeMsg.SUCCESS == result.getCode())
taskInfoDao.deleteByPrimaryKey(reqVo.getId());
ResponseFactory.build();
ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
(Exception e)
ResponseFactory.build(CodeMsg.TASK_EXCEPTION);
List<TaskInfo> selectTasks()
taskInfoDao.selectAll();
id, cron, job_name, status, create_time, update_time
select
from sc_task_info
where id = #id,jdbcType=INTEGER
delete from sc_task_info
where id = #id,jdbcType=INTEGER
SELECT LAST_INSERT_ID()
insert into sc_task_info (cron, job_name, status,
create_time, update_time)
values (#cron,jdbcType=VARCHAR, #jobName,jdbcType=VARCHAR, #status,jdbcType=CHAR,
#createTime,jdbcType=TIMESTAMP, #updateTime,jdbcType=TIMESTAMP)
SELECT LAST_INSERT_ID()
insert into sc_task_info
cron,
job_name,
status,
create_time,
update_time,
#cron,jdbcType=VARCHAR,
#jobName,jdbcType=VARCHAR,
#status,jdbcType=CHAR,
#createTime,jdbcType=TIMESTAMP,
#updateTime,jdbcType=TIMESTAMP,
update sc_task_info
cron = #cron,jdbcType=VARCHAR,
job_name = #jobName,jdbcType=VARCHAR,
status = #status,jdbcType=CHAR,
create_time = #createTime,jdbcType=TIMESTAMP,
update_time = #updateTime,jdbcType=TIMESTAMP,
where id = #id,jdbcType=INTEGER
update sc_task_info
set cron = #cron,jdbcType=VARCHAR,
job_name = #jobName,jdbcType=VARCHAR,
status = #status,jdbcType=CHAR,
create_time = #createTime,jdbcType=TIMESTAMP,
update_time = #updateTime,jdbcType=TIMESTAMP
where id = #id,jdbcType=INTEGER
select * from sc_task_info where job_name=#jobName
select * from sc_task_info
select * from sc_task_info
lombok.Data;
* 任务请求类
**/
TaskInfoReq
Integer id;
cron;
status;
jobName;
int pageSize= int pageCurrent=com.example.demo.quartz.common;
lombok.Data;
code;
String msg;
Object retData;
* 响应工具类
*/
Result code, String errmsg)
Result result = Result();
result.setCode(code);
(errmsg == || errmsg.trim().length() == result.setMsg(CodeMsg.getMsg(code));
result.setMsg(errmsg);
result;
Result code)
commonBuild(code, CodeMsg.getMsg(code));
Result
commonBuild(CodeMsg.SUCCESS,
Result
Result json = commonBuild(CodeMsg.SUCCESS, json.setRetData(data);
json;
EnumTaskEnable
START( STOP( code;
msg;
EnumTaskEnable(code, msg)
getCode()
code;
com.example.demo.quartz.common;
java.util.HashMap;
java.util.Map;
* 公共返回码
*/
Map<Integer, String> MSG = HashMap<Integer, String>();
SUCCESS = ERROR = TASK_NOT_EXITES = TASK_EXCEPTION = TASK_CRON_ERROR = TASK_CRON_DOUBLE =
MSG.put(SUCCESS, MSG.put(ERROR, MSG.put(TASK_NOT_EXITES, MSG.put(TASK_EXCEPTION, MSG.put(TASK_CRON_ERROR, MSG.put(TASK_CRON_DOUBLE,
String errcode)
MSG.get(errcode);
com.example.demo.quartz.utils;
org.springframework.beans.BeansException;
org.springframework.context.ApplicationContext;
org.springframework.context.ApplicationContextAware;
org.springframework.context.annotation.Lazy;
org.springframework.stereotype.Component;
ApplicationContext applicationContext;
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* applicationContext
*/
SpringContextUtils.applicationContext = applicationContext;
* ApplicationContext
*/
ApplicationContext
applicationContext;
* 获取对象
* 这里重写了bean方法,起主要作用
*
* name
* Object 一个以所给名字注册的bean的实例
* BeansException
*/
<T>
(T) applicationContext.getBean(name);
(Exception e)
<T>
applicationContext.getBean(clazz);
(Exception e)
mysql 链接信息
Mapper资源文件存放的路径
Dao 接口文件存放的目录
开启 debug,输出 SQL
com.example.demo.quartz.task;
org.apache.commons.logging.Log;
org.apache.commons.logging.LogFactory;
org.quartz.JobExecutionContext;
org.quartz.JobExecutionException;
org.springframework.scheduling.quartz.QuartzJobBean;
org.springframework.stereotype.Component;
* 定义一个调度器要执行的任务
*/
Log logger = LogFactory.getLog(DongAoJob.class);
JobExecutionException
logger.info(
com.example.demo.quartz;
org.springframework.boot.SpringApplication;
org.springframework.boot.autoconfigure.SpringBootApplication;
SpringApplication.run(DemoJobApplication.class, args);
6. 运行验证
其实挂个简单页面就能轻松完成页面化配置任务,本次用 Postman 方式直接调用任务管理的 API。
6.1 添加任务
此时库任务 Id 为7:
控制台:
6.2 查询任务
6.3 编辑任务
控制台输出:
6.4 暂停任务
http://localhost:15158/task/pause?taskId=7
6.5 恢复任务
http://localhost:15158/task/resume?taskId=7
7. 例行回顾
本文是 Spring Boot 项目集成 Quartz 来实现任务的动态管理,主要是代码,感兴趣的可以自行拿去验证改造并用于实践。
玩转 Spring Boot 集成定时任务篇就写到这里,希望大家能够喜欢。
一起聊技术、谈业务、喷架构,少走弯路,不踩大坑,会持续输出更多精彩分享,欢迎关注,敬请期待!
历史系列文章:
玩转 Spring Boot 入门篇
玩转 Spring Boot 集成篇(MySQL、Druid、HikariCP)
玩转 Spring Boot 集成篇(MyBatis、JPA、事务支持)
玩转 Spring Boot 集成篇(Redis)
玩转 Spring Boot 集成篇(Actuator、Spring Boot Admin)
玩转 Spring Boot 集成篇(RabbitMQ)
玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)
Spring Boot集成Quartz注入Spring管理的类
摘要: 在Spring Boot中使用Quartz时,在JOB中一般需要引用Spring管理的Bean,通过定义Job Factory实现自动注入。
Spring有自己的Schedule定时任务,在Spring boot中使用的时候,不能动态管理JOB,于是就使用Quartz来实现。
在Spring Boot中配置Quartz:
import java.io.IOException;
import java.util.Properties;
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.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
@EnableScheduling
public class QuartzSchedule {
@Autowired
private MyJobFactory myJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setOverwriteExistingJobs(true);
// 延时启动
factory.setStartupDelay(20);
// 加载quartz数据源配置
factory.setQuartzProperties(quartzProperties());
// 自定义Job Factory,用于Spring注入
factory.setJobFactory(myJobFactory);
return factory;
}
/**
* 加载quartz数据源配置
*
* @return
* @throws IOException
*/
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}
为了在JOB中使用Spring管理的Bean,需要重新定义一个Job Factory:
@Component
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
// 进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
然后在JOB中就可以使用Spring管理的Bean了
public class MyJob implements Job, Serializable {
private static final long serialVersionUID = 1L;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private SomeService someService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
someService.doSomething();
}
}
下面代码是创建JOB:
JobDetail jobDetail = JobBuilder.newJob(((Job) Class.forName(job.getClazz()).newInstance()).getClass())
.withIdentity(job.getJobName(), job.getJobGroup()).build();
jobDetail.getJobDataMap().put("extdata", job.getExtData());
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression())
.withMisfireHandlingInstructionDoNothing();
// 构建一个trigger
TriggerBuilder<CronTrigger> triggerBuilder = TriggerBuilder.newTrigger().withIdentity(triggerKey)
.withSchedule(scheduleBuilder);
if (job.getStartTime() != null) {
triggerBuilder.startAt(job.getStartTime());
}
if (job.getEndTime() != null) {
triggerBuilder.endAt(job.getEndTime());
}
CronTrigger trigger = triggerBuilder.build();
scheduler.scheduleJob(jobDetail, trigger);// 注入到管理类
https://my.oschina.net/hhaijun/blog/698498
以上是关于玩转 Spring Boot 集成篇(任务动态管理代码篇)的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot集成Quartz注入Spring管理的类
玩转Spring Boot 集成Dubbo
玩转 Spring Boot 原理篇(源码环境搭建)
玩转 Spring Boot 原理篇(自动装配源码剖析)
玩转 Spring Boot 原理篇(核心注解知多少)
Quartz+Spring Boot实现动态管理定时任务