SpringBoot Schedule调度任务的动态管理方法是什么
学习文章要努力,但是不要急!今天的这篇文章《SpringBoot Schedule调度任务的动态管理方法是什么》将会介绍到等等知识点,如果你想深入学习文章,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!
前言
定时任务动态管理分为两种方式:
方式一:Web前台配置Trigger触发器(关联Cron)、ThreadPoolTaskScheduler类创建Scheduler方式下进行Schedule调度任务的动态管理
方式二:基于已创建的Schedule调度任务的动态管理,即以组件类 @Scheduled注解声明Schedule调度,在启动程序前一次性初始化,如:
@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()) + "测试测试");
}
}缺陷:目前无法在运行期间增加Schedule以及stop、Start、Reset等管理。
一、架构流程图

二、代码实现流程
架构为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数据连接池 --> <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定时框架--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> <version>2.2.5.RELEASE</version> </dependency> </dependencies> <build> <plugins> <!-- 打包跳过测试 --> <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:
# 单个文件大小
max-file-size: 2000MB
# 设置总上传的文件大小
max-request-size: 4000MB
#json 时间戳统一转换
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参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 1
min-idle: 1
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'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 设置
mybatis-plus:
mapper-locations: classpath*:com/merak/hyper/automation/persist/**/xml/*Mapper.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
id-type: ID_WORKER_STR
# 默认数据库表下划线命名
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.代码流程
启动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: 工单任务调度
* @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: 实例化ThreadPoolTaskScheduler对象,用于创建ScheduledFuture<?> scheduledFuture
*/
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(taskSchedulerCorePoolSize);
taskScheduler.setThreadNamePrefix(threadNamePrefix);
taskScheduler.setWaitForTasksToCompleteOnShutdown(false);
taskScheduler.setAwaitTerminationSeconds(awaitTerminationSeconds);
/**需要实例化线程*/
taskScheduler.initialize();
// isinitialized = true;
log.info("初始化ThreadPoolTaskScheduler ThreadNamePrefix=" + threadNamePrefix + ",PoolSize=" + taskSchedulerCorePoolSize
+ ",awaitTerminationSeconds=" + awaitTerminationSeconds);
return taskScheduler;
}
/**
* @description: 实例化ThreadPoolTaskExecutor对象,管理asyncTask启动的线程,应用类为 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);
//修改拒绝策略为使用当前线程执行
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//初始化线程池
taskExecutor.initialize();
return taskExecutor;
}
}一、启动时项目启动时,加载任务关联的触发器,并全量执行流程。
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;
/**
* 项目启动时,加载数字员工关联的触发器,并全量执行
* @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("项目启动:加载数字员工关联的触发器信息并全量执行," + 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("数字员工关联的触发器信息不正确,员工记录数:"+busWorkflows.size()+",触发器记录数:"+triggerInfos.size());
}
else{
//数字员工关联的触发器信息
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("数字员工关联的触发器信息全量执行完成,数字员工定时个数:"+loadWfidAndTriggerInfo.size()+","+df.format(LocalDateTime.now()));
}
}
}
核心代码:
```java
ScheduleUtil.start(new ScheduleTask(wfId,String.valueOf(workflow.getWfCreateuserId()),taskService), entry.getValue());Scheduler管理工具类:启动、取消、修改等管理
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管理工具类:启动、取消、修改等管理
*/
public class ScheduleUtil {
public static final Logger log = LoggerFactory.getLogger(ScheduleUtil.class);
private static ThreadPoolTaskScheduler threadPoolTaskScheduler = SpringContextUtils.getBean(ThreadPoolTaskScheduler.class);
//存储[数字员工wfI,dScheduledFuture]集合
private static Map<String, ScheduledFuture<?>> scheduledFutureMap = new HashMap<>();
/**
* 启动
*
* @param scheduleTask 定时任务
* @param triggerInfo
*/
public static boolean start(ScheduleTask scheduleTask, AutoTriggerInfo triggerInfo) {
String wfId = scheduleTask.getId();
log.info("启动数字员工"+wfId+"定时任务线程" + scheduleTask.getId());
ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler.schedule(scheduleTask, new CronTrigger(triggerInfo.getLogicConfig()));
scheduledFutureMap.put(wfId, scheduledFuture);
return true;
}
/**
* 取消
*
* @param scheduleTask 定时任务
*/
public static boolean cancel(ScheduleTask scheduleTask) {
log.info("关闭定时任务线程 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 定时任务
* @param triggerInfo
*/
public static boolean reset(ScheduleTask scheduleTask, AutoTriggerInfo triggerInfo) {
//先取消定时任务
cancel(scheduleTask);
//然后启动新的定时任务
start(scheduleTask, triggerInfo);
return true;
}
}ScheduleTask类:ScheduleTask任务类
package com.merak.hyper.automation.Scheduling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version 1.0
* @ClassName: ScheduleTask
* @description: ScheduleTask,关联任务id、用户id和具体执行的TaskService类,实现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 任务ID
* @param service 业务类
*/
public ScheduleTask(String id, String userId, TaskService service) {
this.id = id;
this.userId = userId;
this.service = service;
}
@Override
public void run() {
log.info("ScheduleTask-执行数字员工消息的发送,id:"+ this.id + ",用户id:"+userId);
service.work(this.id,this.userId);
}
}/**
* @version 1.0
* @ClassName: TaskService
* @description: TaskService
*/
public interface TaskService {
/**
* 业务处理方法
* @param keyword 关键参数
* @param userId
*/
void work(String keyword,String userId);
}
/**
* @description: TaskService实现类,具体执行定时调度的业务
*/
@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("定时任务:根据数字员工wfId"+ wfId +",用户id:"+userId+",发送消息...");
//sendRobotMsg(wfId,userId);
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}二、通过WEB配置的变更,动态管理定时任务
ScheduledController类:scheduled Web业务层:启动、取消、修改等管理schedule
调度任务信息变更(如1:Trigger Cron变更 2:任务停止 3:任务新增加等)
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业务层:启动、取消、修改等管理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类:对外提供ScheduledHelper管理:创建、变更、停止
```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:对外提供ScheduledHelper管理:创建、变更、停止
*/
@Component
public class ScheduledHelper {
public static final Logger log = LoggerFactory.getLogger(ScheduledHelper.class);
/**
* @description: 对外(Web)提供异步的Scheduleds增加操作
*/
@Async("asyncTaskExecutor")
public void addScheduleds(ScheduledApiVo scheduledApiVo, AutoTriggerInfo triggerInfo) {
//addSchedule任务
log.warn("创建原数字员工["+scheduledApiVo.getWfId()+"],同步启动Schedule任务");
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任务
log.warn("数字员工["+scheduledApiVo.getWfId()+"]关联的触发器信息cron值改变,变更Schedule任务");
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任务
log.warn("原数字员工["+scheduledApiVo.getWfId()+"]无效,同步停止Schedule任务");
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对象
*/
@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业务层Api传递参数Vo类
*/
public class ScheduledApiVo implements Serializable {
private String wfId;
private String userId;
private String triggerId;
//set get 略
}最终:Web端通过发送Http请求 ,调用ScheduledHelper管理类接口,实现Scheduled创建、变更、停止操作
log.info("3:云托管更新启动数字员工操作");
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("调用任务调度中心消息发送失败,地址:"+quartzUrl);
}
else {
JSONObject jsonObject = JSON.parseObject(resp);
if( "200".equals(String.valueOf(jsonObject.get("code"))) ){
result = true;
}
else{
log.error("调用任务调度中心失败,msg:"+String.valueOf(jsonObject.get("msg")));
}
}
}catch (Exception e){
log.error("调用任务调度中心失败,msg:"+e.getMessage());
}
return result;
}<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency>
以上就是《SpringBoot Schedule调度任务的动态管理方法是什么》的详细内容,更多关于SpringBoot,Schedule的资料请关注golang学习网公众号!
PHP 函数常见错误的性能影响
- 上一篇
- PHP 函数常见错误的性能影响
- 下一篇
- GitHub 最新 AI 工具可帮助用户自动修复代码中的错误和漏洞
-
- 文章 · java教程 | 13分钟前 |
- Java登录鉴权流程及Token机制解析
- 353浏览 收藏
-
- 文章 · java教程 | 8小时前 |
- 共享接口高效测试方法与技巧
- 182浏览 收藏
-
- 文章 · java教程 | 8小时前 |
- Java博客评论功能实现详解
- 185浏览 收藏
-
- 文章 · java教程 | 8小时前 | java
- ConcurrentHashMap性能优化解析
- 464浏览 收藏
-
- 文章 · java教程 | 9小时前 |
- JavaFormatter格式化技巧与使用方法
- 215浏览 收藏
-
- 文章 · java教程 | 9小时前 |
- Java简易邮件发送教程实现方法
- 429浏览 收藏
-
- 文章 · java教程 | 9小时前 |
- Java异常处理技巧与捕获方法
- 421浏览 收藏
-
- 文章 · java教程 | 10小时前 |
- Java代理与AOP实现详解
- 182浏览 收藏
-
- 文章 · java教程 | 10小时前 |
- Java项目字符集配置与环境设置详解
- 315浏览 收藏
-
- 文章 · java教程 | 10小时前 | 任务队列
- JavaBlockingQueue实现高并发任务队列
- 112浏览 收藏
-
- 文章 · java教程 | 10小时前 |
- 检查字符串是否含小写字母的两种方法
- 101浏览 收藏
-
- 文章 · java教程 | 11小时前 | java 递归
- 循环与递归的区别是什么
- 244浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3696次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3963次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3905次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 5078次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 4276次使用
-
- 提升Java功能开发效率的有力工具:微服务架构
- 2023-10-06 501浏览
-
- 掌握Java海康SDK二次开发的必备技巧
- 2023-10-01 501浏览
-
- 如何使用java实现桶排序算法
- 2023-10-03 501浏览
-
- Java开发实战经验:如何优化开发逻辑
- 2023-10-31 501浏览
-
- 如何使用Java中的Math.max()方法比较两个数的大小?
- 2023-11-18 501浏览

