SpringBoot?Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理
前言
定時(shí)任務(wù)動(dòng)態(tài)管理分為兩種方式:
方式一:Web前臺(tái)配置Trigger觸發(fā)器(關(guān)聯(lián)Cron)、ThreadPoolTaskScheduler類創(chuàng)建Scheduler方式下進(jìn)行Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理
方式二:基于已創(chuàng)建的Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理,即以組件類 @Scheduled注解聲明Schedule調(diào)度,在啟動(dòng)程序前一次性初始化,如:
@Component
public class TestTask {
private DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Scheduled(cron = "0/2 * * * * ?")
public void robReceiveExpireTask() {
System.out.println(df.format(LocalDateTime.now()) + "測(cè)試測(cè)試");
}
}
解決方案參考 SpringBoot的定時(shí)任務(wù)動(dòng)態(tài)管理
缺陷:目前無法在運(yùn)行期間增加Schedule以及stop、Start、Reset等管理。
本文章主要編寫方式一的實(shí)現(xiàn)方案,主要從架構(gòu)流程圖配合代碼進(jìn)行說明。
一、架構(gòu)流程圖

二、代碼實(shí)現(xiàn)流程
架構(gòu)為SpringBoot + Spring + mybatis-plus
1.引入庫
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>merak-hyper-automation-boot</artifactId>
<groupId>com.merak.automation</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>automation-quartz</artifactId>
<packaging>jar</packaging>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!-- Spring框架基本的核心工具 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- SpringWeb模塊 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid數(shù)據(jù)連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!--引入quartz定時(shí)框架-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包跳過測(cè)試 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>resources目錄下文件/application.yml:
spring:
profiles:
active: dev
resources目錄下文件/application-dev.yml:
server:
port: 12105
servlet:
context-path: /automation-quartzmanagement:
endpoints:
web:
exposure:
include: '*'# Spring配置
spring:
resources:
static-locations: classpath:/static/,classpath:/templates/
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern: /**
application:
name: automation-workflow
main:
allow-bean-definition-overriding: true
# 文件上傳
servlet:
multipart:
# 單個(gè)文件大小
max-file-size: 2000MB
# 設(shè)置總上傳的文件大小
max-request-size: 4000MB
#json 時(shí)間戳統(tǒng)一轉(zhuǎn)換
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
aop:
proxy-target-class: true
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
dynamic:
druid:
# 全局druid參數(shù),絕大部分值和默認(rèn)保持一致。(現(xiàn)已支持的參數(shù)如下,不清楚含義不要亂設(shè)置)
# 連接池的配置信息
# 初始化大小,最小,最大
initial-size: 1
min-idle: 1
maxActive: 20
# 配置獲取連接等待超時(shí)的時(shí)間
maxWait: 60000
# 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打開PSCache,并且指定每個(gè)連接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計(jì),'wall'用于防火墻
filters: stat,wall,slf4j
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://127.0.0.1:3308/merak_dev?characterEncoding=UTF-8&useUnicode=true&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver#mybatis plus 設(shè)置
mybatis-plus:
mapper-locations: classpath*:com/merak/hyper/automation/persist/**/xml/*Mapper.xml
global-config:
# 關(guān)閉MP3.0自帶的banner
banner: false
db-config:
id-type: ID_WORKER_STR
# 默認(rèn)數(shù)據(jù)庫表下劃線命名
table-underline: true
configuration:
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
level:
com.merar.hyper: debug
com.merak.hyper.automation.persist.**.mapper: debug
org.springframework: warn
2.代碼流程
啟動(dòng)MerakQuartzApplication類
package com.merak.hyper.automation;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author chenjun
* @version 1.0
* @ClassName: MerakQuartzApplication
* @description: 工單任務(wù)調(diào)度
* @date 2022/9/22 10:30
*/
@EnableScheduling
@EnableAsync
@MapperScan(basePackages = {"com.merak.hyper.automation.persist.**.mapper"})
@SpringBootApplication(scanBasePackages = {"com.merak.hyper.automation.**"}, exclude = {SecurityAutoConfiguration.class})
public class MerakQuartzApplication {
public static final Logger log = LoggerFactory.getLogger(MerakQuartzApplication.class);
public static void main(String[] args) {
SpringApplication.run(MerakQuartzApplication.class, args);
}
private int taskSchedulerCorePoolSize = 15;
private int awaitTerminationSeconds = 60;
private String threadNamePrefix = "taskExecutor-";
/**
* @description: 實(shí)例化ThreadPoolTaskScheduler對(duì)象,用于創(chuàng)建ScheduledFuture<?> scheduledFuture
*/
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(taskSchedulerCorePoolSize);
taskScheduler.setThreadNamePrefix(threadNamePrefix);
taskScheduler.setWaitForTasksToCompleteOnShutdown(false);
taskScheduler.setAwaitTerminationSeconds(awaitTerminationSeconds);
/**需要實(shí)例化線程*/
taskScheduler.initialize();
// isinitialized = true;
log.info("初始化ThreadPoolTaskScheduler ThreadNamePrefix=" + threadNamePrefix + ",PoolSize=" + taskSchedulerCorePoolSize
+ ",awaitTerminationSeconds=" + awaitTerminationSeconds);
return taskScheduler;
}
/**
* @description: 實(shí)例化ThreadPoolTaskExecutor對(duì)象,管理asyncTask啟動(dòng)的線程,應(yīng)用類為 ScheduledHelper
*/
@Bean("asyncTaskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(50);
taskExecutor.setQueueCapacity(200);
taskExecutor.setKeepAliveSeconds(60);
taskExecutor.setThreadNamePrefix("asyncTaskExecutor-");
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.setAwaitTerminationSeconds(60);
//修改拒絕策略為使用當(dāng)前線程執(zhí)行
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//初始化線程池
taskExecutor.initialize();
return taskExecutor;
}
}一、啟動(dòng)時(shí)項(xiàng)目啟動(dòng)時(shí),加載任務(wù)關(guān)聯(lián)的觸發(fā)器,并全量執(zhí)行流程。
initLineRunner類:
package com.merak.hyper.automation.Scheduling;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.merak.hyper.automation.persist.entity.AutoTriggerInfo;
import com.merak.hyper.automation.persist.entity.BusWorkflow;
import com.merak.hyper.automation.persist.service.IAutoTriggerInfoService;
import com.merak.hyper.automation.persist.service.IBusWorkflowService;
import com.merak.hyper.automation.util.CommonUtil;
import com.merak.hyper.automation.util.ScheduleUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 項(xiàng)目啟動(dòng)時(shí),加載數(shù)字員工關(guān)聯(lián)的觸發(fā)器,并全量執(zhí)行
* @Date: 2020/12/25:16:00
**/
@Component
@Order(1)
public class initLineRunner implements CommandLineRunner {
public static final Logger log = LoggerFactory.getLogger(initLineRunner.class);
private DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Autowired
private TaskService taskService;
@Autowired
private IAutoTriggerInfoService triggerInfoService;
@Autowired
private IBusWorkflowService workflowService;
@Override
public void run(String... args) {
log.info("項(xiàng)目啟動(dòng):加載數(shù)字員工關(guān)聯(lián)的觸發(fā)器信息并全量執(zhí)行," + df.format(LocalDateTime.now()));
QueryWrapper<BusWorkflow> wrapper = new QueryWrapper<>();
wrapper.eq("wf_type", "3");//3:云托管
wrapper.eq("wf_state", "1");
List<BusWorkflow> busWorkflows = workflowService.list(wrapper);
List<AutoTriggerInfo> triggerInfos = triggerInfoService.list();
if( 0 == busWorkflows.size() || 0 == triggerInfos.size() ){
log.info("數(shù)字員工關(guān)聯(lián)的觸發(fā)器信息不正確,員工記錄數(shù):"+busWorkflows.size()+",觸發(fā)器記錄數(shù):"+triggerInfos.size());
}
else{
//數(shù)字員工關(guān)聯(lián)的觸發(fā)器信息
Map<String,AutoTriggerInfo> loadWfidAndTriggerInfo = CommonUtil.loadWfidAndTriggerInfo(busWorkflows,triggerInfos);
Iterator<Map.Entry<String, AutoTriggerInfo>> entries = loadWfidAndTriggerInfo.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, AutoTriggerInfo> entry = entries.next();
String wfId = entry.getKey();
BusWorkflow workflow = busWorkflows.stream().filter( t -> wfId.equals(t.getWfId()) ).findAny().orElse(null);
if( null != workflow ){
ScheduleUtil.start(new ScheduleTask(wfId,String.valueOf(workflow.getWfCreateuserId()),taskService), entry.getValue());
}
}
log.info("數(shù)字員工關(guān)聯(lián)的觸發(fā)器信息全量執(zhí)行完成,數(shù)字員工定時(shí)個(gè)數(shù):"+loadWfidAndTriggerInfo.size()+","+df.format(LocalDateTime.now()));
}
}
}
核心代碼:
```java
ScheduleUtil.start(new ScheduleTask(wfId,String.valueOf(workflow.getWfCreateuserId()),taskService), entry.getValue());Scheduler管理工具類:啟動(dòng)、取消、修改等管理
package com.merak.hyper.automation.util;
import com.merak.hyper.automation.Scheduling.ScheduleTask;
import com.merak.hyper.automation.persist.entity.AutoTriggerInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
/**
* @version 1.0
* @ClassName: ScheduleUtil
* @description: Scheduler管理工具類:啟動(dòng)、取消、修改等管理
*/
public class ScheduleUtil {
public static final Logger log = LoggerFactory.getLogger(ScheduleUtil.class);
private static ThreadPoolTaskScheduler threadPoolTaskScheduler = SpringContextUtils.getBean(ThreadPoolTaskScheduler.class);
//存儲(chǔ)[數(shù)字員工wfI,dScheduledFuture]集合
private static Map<String, ScheduledFuture<?>> scheduledFutureMap = new HashMap<>();
/**
* 啟動(dòng)
*
* @param scheduleTask 定時(shí)任務(wù)
* @param triggerInfo
*/
public static boolean start(ScheduleTask scheduleTask, AutoTriggerInfo triggerInfo) {
String wfId = scheduleTask.getId();
log.info("啟動(dòng)數(shù)字員工"+wfId+"定時(shí)任務(wù)線程" + scheduleTask.getId());
ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler.schedule(scheduleTask, new CronTrigger(triggerInfo.getLogicConfig()));
scheduledFutureMap.put(wfId, scheduledFuture);
return true;
}
/**
* 取消
*
* @param scheduleTask 定時(shí)任務(wù)
*/
public static boolean cancel(ScheduleTask scheduleTask) {
log.info("關(guān)閉定時(shí)任務(wù)線程 taskId " + scheduleTask.getId());
ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(scheduleTask.getId());
if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
scheduledFuture.cancel(false);
}
scheduledFutureMap.remove(scheduleTask.getId());
return true;
}
/**
* 修改
*
* @param scheduleTask 定時(shí)任務(wù)
* @param triggerInfo
*/
public static boolean reset(ScheduleTask scheduleTask, AutoTriggerInfo triggerInfo) {
//先取消定時(shí)任務(wù)
cancel(scheduleTask);
//然后啟動(dòng)新的定時(shí)任務(wù)
start(scheduleTask, triggerInfo);
return true;
}
}ScheduleTask類:ScheduleTask任務(wù)類
package com.merak.hyper.automation.Scheduling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version 1.0
* @ClassName: ScheduleTask
* @description: ScheduleTask,關(guān)聯(lián)任務(wù)id、用戶id和具體執(zhí)行的TaskService類,實(shí)現(xiàn)Runnable類
*/
public class ScheduleTask implements Runnable {
private static final int TIMEOUT = 30000;
private String id;
private String userId;
private TaskService service;
public static final Logger log = LoggerFactory.getLogger(ScheduleTask.class);
public String getId() {
return id;
}
/**
* @param id 任務(wù)ID
* @param service 業(yè)務(wù)類
*/
public ScheduleTask(String id, String userId, TaskService service) {
this.id = id;
this.userId = userId;
this.service = service;
}
@Override
public void run() {
log.info("ScheduleTask-執(zhí)行數(shù)字員工消息的發(fā)送,id:"+ this.id + ",用戶id:"+userId);
service.work(this.id,this.userId);
}
}
/**
* @version 1.0
* @ClassName: TaskService
* @description: TaskService
*/
public interface TaskService {
/**
* 業(yè)務(wù)處理方法
* @param keyword 關(guān)鍵參數(shù)
* @param userId
*/
void work(String keyword,String userId);
}
/**
* @description: TaskService實(shí)現(xiàn)類,具體執(zhí)行定時(shí)調(diào)度的業(yè)務(wù)
*/
@Service
public class TaskServiceImpl implements TaskService {
public static final Logger log = LoggerFactory.getLogger(TaskServiceImpl.class);
@Autowired
private IAutoDeviceInfoService deviceInfoService;
@Override
public void work(String wfId,String userId) {
try {
log.info("定時(shí)任務(wù):根據(jù)數(shù)字員工wfId"+ wfId +",用戶id:"+userId+",發(fā)送消息...");
//sendRobotMsg(wfId,userId);
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
二、通過WEB配置的變更,動(dòng)態(tài)管理定時(shí)任務(wù)
ScheduledController類:scheduled Web業(yè)務(wù)層:?jiǎn)?dòng)、取消、修改等管理schedule
調(diào)度任務(wù)信息變更(如1:Trigger Cron變更 2:任務(wù)停止 3:任務(wù)新增加等)
package com.merak.hyper.automation.controller;
import com.merak.hyper.automation.common.core.domain.AjaxResult;
import com.merak.hyper.automation.common.core.vo.ScheduledApiVo;
import com.merak.hyper.automation.persist.entity.AutoTriggerInfo;
import com.merak.hyper.automation.persist.service.IAutoTriggerInfoService;
import com.merak.hyper.automation.util.ScheduledHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @version 1.0
* @ClassName: ScheduledController
* @description: scheduled Web業(yè)務(wù)層:?jiǎn)?dòng)、取消、修改等管理schedule
*/
@RestController
@RequestMapping("/api/scheduled")
public class ScheduledController {
public static final Logger log = LoggerFactory.getLogger(ScheduledController.class);
@Autowired
private IAutoTriggerInfoService triggerInfoService;
@Autowired
private ScheduledHelper scheduledHelper;
@PostMapping("/add")
public AjaxResult addScheduleds(@RequestBody ScheduledApiVo scheduledApiVo){
AutoTriggerInfo autoTriggerInfo = triggerInfoService.getById(scheduledApiVo.getTriggerId());
scheduledHelper.addScheduleds(scheduledApiVo,autoTriggerInfo);
return AjaxResult.success();
}
@PostMapping("/reset")
public AjaxResult resetScheduleds(@RequestBody ScheduledApiVo scheduledApiVo){
AutoTriggerInfo autoTriggerInfo = triggerInfoService.getById(scheduledApiVo.getTriggerId());
scheduledHelper.resetScheduleds(scheduledApiVo,autoTriggerInfo);
return AjaxResult.success();
}
@PostMapping("/stop")
public AjaxResult stopScheduleds(@RequestBody ScheduledApiVo scheduledApiVo){
AutoTriggerInfo autoTriggerInfo = triggerInfoService.getById(scheduledApiVo.getTriggerId());
scheduledHelper.stopScheduleds(scheduledApiVo);
return AjaxResult.success();
}
}
ScheduledHelper類:對(duì)外提供ScheduledHelper管理:創(chuàng)建、變更、停止
```java
package com.merak.hyper.automation.util;
import com.merak.hyper.automation.Scheduling.ScheduleTask;
import com.merak.hyper.automation.Scheduling.TaskService;
import com.merak.hyper.automation.common.core.vo.ScheduledApiVo;
import com.merak.hyper.automation.persist.entity.AutoTriggerInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @version 1.0
* @ClassName: ScheduledHelper
* @description:對(duì)外提供ScheduledHelper管理:創(chuàng)建、變更、停止
*/
@Component
public class ScheduledHelper {
public static final Logger log = LoggerFactory.getLogger(ScheduledHelper.class);
/**
* @description: 對(duì)外(Web)提供異步的Scheduleds增加操作
*/
@Async("asyncTaskExecutor")
public void addScheduleds(ScheduledApiVo scheduledApiVo, AutoTriggerInfo triggerInfo) {
//addSchedule任務(wù)
log.warn("創(chuàng)建原數(shù)字員工["+scheduledApiVo.getWfId()+"],同步啟動(dòng)Schedule任務(wù)");
TaskService taskService = SpringContextUtils.getBean(TaskService.class);
ScheduleUtil.start(new ScheduleTask(scheduledApiVo.getWfId(), scheduledApiVo.getUserId(), taskService), triggerInfo);
}
@Async("asyncTaskExecutor")
public void resetScheduleds(ScheduledApiVo scheduledApiVo,AutoTriggerInfo triggerInfo) {
//cron值改變,變更Schedule任務(wù)
log.warn("數(shù)字員工["+scheduledApiVo.getWfId()+"]關(guān)聯(lián)的觸發(fā)器信息cron值改變,變更Schedule任務(wù)");
TaskService taskService = SpringContextUtils.getBean(TaskService.class);
ScheduleUtil.reset(new ScheduleTask(scheduledApiVo.getWfId(), scheduledApiVo.getUserId(), taskService), triggerInfo);
}
@Async("asyncTaskExecutor")
public void stopScheduleds(ScheduledApiVo scheduledApiVo) {
//移除Wfid,停止原Schedule任務(wù)
log.warn("原數(shù)字員工["+scheduledApiVo.getWfId()+"]無效,同步停止Schedule任務(wù)");
TaskService taskService = SpringContextUtils.getBean(TaskService.class);
ScheduleUtil.cancel(new ScheduleTask(scheduledApiVo.getWfId(), scheduledApiVo.getUserId(), taskService));
}
}SpringContextUtils類:
package com.merak.hyper.automation.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @version 1.0
* @ClassName: SpringContextUtils
* @description: 加載Class對(duì)象
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
}
ScheduledApiVo類:
import java.io.Serializable;
/**
* @version 1.0
* @ClassName: ScheduledApiVo
* @description: scheduled Web業(yè)務(wù)層Api傳遞參數(shù)Vo類
*/
public class ScheduledApiVo implements Serializable {
private String wfId;
private String userId;
private String triggerId;
//set get 略
}
最終:Web端通過發(fā)送Http請(qǐng)求 ,調(diào)用ScheduledHelper管理類接口,實(shí)現(xiàn)Scheduled創(chuàng)建、變更、停止操作
log.info("3:云托管更新啟動(dòng)數(shù)字員工操作");
ScheduledApiVo scheduledApiVo = new ScheduledApiVo();
scheduledApiVo.setWfId(wfId);
scheduledApiVo.setUserId(String.valueOf(updateUserId));
scheduledApiVo.setTriggerId(newTriggerInfo.getId());
String webHookBody = JSON.toJSONString(scheduledApiVo);
EmsApiUtil.SendQuartzMessage(url, "add", webHookBody);
******************** 分隔 ************************
public static boolean SendQuartzMessage(String quartzUrl, String method, String webHookBody){
boolean result = false;
try{
//org.apache.httpcomponents.httpclient sendPost,pom依賴如下dependency
String resp = HttpClientUtil.sendPostByJson(quartzUrl+"/"+method, webHookBody,0);
if( "error".equals(resp) || resp.contains("405 Not Allowed")){
log.error("調(diào)用任務(wù)調(diào)度中心消息發(fā)送失敗,地址:"+quartzUrl);
}
else {
JSONObject jsonObject = JSON.parseObject(resp);
if( "200".equals(String.valueOf(jsonObject.get("code"))) ){
result = true;
}
else{
log.error("調(diào)用任務(wù)調(diào)度中心失敗,msg:"+String.valueOf(jsonObject.get("msg")));
}
}
}catch (Exception e){
log.error("調(diào)用任務(wù)調(diào)度中心失敗,msg:"+e.getMessage());
}
return result;
}
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
到此這篇關(guān)于SpringBoot Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理的文章就介紹到這了,更多相關(guān)SpringBoot Schedule內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot?ScheduledTaskRegistrar解決動(dòng)態(tài)定時(shí)任務(wù)思路詳解
- SpringBoot使用SchedulingConfigurer實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)多機(jī)器部署問題(推薦)
- SpringBoot中定時(shí)任務(wù)@Scheduled注解的使用解讀
- Springboot-admin整合Quartz實(shí)現(xiàn)動(dòng)態(tài)管理定時(shí)任務(wù)的過程詳解
- SpringBoot定時(shí)任務(wù)實(shí)現(xiàn)數(shù)據(jù)同步的方法
- SpringBoot定時(shí)任務(wù)多線程實(shí)現(xiàn)示例
- MySQL數(shù)據(jù)庫中數(shù)值字段類型長(zhǎng)度int(11)和Decimal(M,D)詳解
相關(guān)文章
Spring?boot框架JWT實(shí)現(xiàn)用戶賬戶密碼登錄驗(yàn)證流程
這篇文章主要介紹了Springboot框架JWT實(shí)現(xiàn)用戶賬戶密碼登錄驗(yàn)證,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
自定義@RequestBody注解如何獲取JSON數(shù)據(jù)
這篇文章主要介紹了自定義@RequestBody注解如何獲取JSON數(shù)據(jù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Java利用TCP實(shí)現(xiàn)服務(wù)端向客戶端消息群發(fā)的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java如何利用TCP協(xié)議實(shí)現(xiàn)服務(wù)端向客戶端消息群發(fā)功能,文中的示例代碼講解詳細(xì),需要的可以參考下,希望對(duì)你有所幫助2022-08-08
Java用POI解析excel并獲取所有單元格數(shù)據(jù)的實(shí)例
下面小編就為大家?guī)硪黄狫ava用POI解析excel并獲取所有單元格數(shù)據(jù)的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
Java實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn)猜拳游戲
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn)猜拳游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
fastjson生成json時(shí)Null屬性不顯示的解決方法
下面小編就為大家?guī)硪黄猣astjson生成json時(shí)Null屬性不顯示的解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02

