国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Boot如何實現定時任務的動態增刪啟停詳解

Spring Boot如何實現定時任務的動態增刪啟停詳解

2020-07-20 11:38極客網 Java教程

這篇文章主要給大家介紹了關于Spring Boot如何實現定時任務的動態增刪啟停的相關資料,文中通過示例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

我以為動態停啟定時任務一般用quartz,沒想到還可以通過ScheduledTaskRegistrar來拓展。但是分布式場景,建議還是用quartz吧!

在 spring boot 項目中,可以通過 @EnableScheduling 注解和 @Scheduled 注解實現定時任務,也可以通過 SchedulingConfigurer 接口來實現定時任務。但是這兩種方式不能動態添加、刪除、啟動、停止任務。要實現動態增刪啟停定時任務功能,比較廣泛的做法是集成 Quartz 框架。

但是本人的開發原則是:在滿足項目需求的情況下,盡量少的依賴其它框架,避免項目過于臃腫和復雜。查看 spring-context 這個 jar 包中 org.springframework.scheduling.ScheduledTaskRegistrar 這個類的源代碼,發現可以通過改造這個類就能實現動態增刪啟停定時任務功能。

Spring Boot如何實現定時任務的動態增刪啟停詳解

定時任務列表頁

Spring Boot如何實現定時任務的動態增刪啟停詳解

定時任務執行日志

添加執行定時任務的線程池配置類

?
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class SchedulingConfig {
 @Bean
 public TaskScheduler taskScheduler() {
  ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
  
  taskScheduler.setPoolSize(4);
  taskScheduler.setRemoveOnCancelPolicy(true);
  taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");
  return taskScheduler;
 }
}

添加 ScheduledFuture 的包裝類。ScheduledFuture 是 ScheduledExecutorService 定時任務線程池的執行結果。

?
1
2
3
4
5
6
7
8
9
10
11
12
public final class ScheduledTask {
 
 volatile ScheduledFuture<?> future;
 
 
 public void cancel() {
  ScheduledFuture<?> future = this.future;
  if (future != null) {
   future.cancel(true);
  }
 }
}

添加 Runnable 接口實現類,被定時任務線程池調用,用來執行指定 bean 里面的方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class SchedulingRunnable implements Runnable {
 
 private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);
 
 private String beanName;
 
 private String methodName;
 
 private String params;
 
 public SchedulingRunnable(String beanName, String methodName) {
  this(beanName, methodName, null);
 }
 
 public SchedulingRunnable(String beanName, String methodName, String params) {
  this.beanName = beanName;
  this.methodName = methodName;
  this.params = params;
 }
 
 @Override
 public void run() {
  logger.info("定時任務開始執行 - bean:{},方法:{},參數:{}", beanName, methodName, params);
  long startTime = System.currentTimeMillis();
 
  try {
   Object target = SpringContextUtils.getBean(beanName);
 
   Method method = null;
   if (StringUtils.isNotEmpty(params)) {
    method = target.getClass().getDeclaredMethod(methodName, String.class);
   } else {
    method = target.getClass().getDeclaredMethod(methodName);
   }
 
   ReflectionUtils.makeAccessible(method);
   if (StringUtils.isNotEmpty(params)) {
    method.invoke(target, params);
   } else {
    method.invoke(target);
   }
  } catch (Exception ex) {
   logger.error(String.format("定時任務執行異常 - bean:%s,方法:%s,參數:%s ", beanName, methodName, params), ex);
  }
 
  long times = System.currentTimeMillis() - startTime;
  logger.info("定時任務執行結束 - bean:{},方法:{},參數:{},耗時:{} 毫秒", beanName, methodName, params, times);
 }
 
 @Override
 public boolean equals(Object o) {
  if (this == o) return true;
  if (o == null || getClass() != o.getClass()) return false;
  SchedulingRunnable that = (SchedulingRunnable) o;
  if (params == null) {
   return beanName.equals(that.beanName) &&
     methodName.equals(that.methodName) &&
     that.params == null;
  }
 
  return beanName.equals(that.beanName) &&
    methodName.equals(that.methodName) &&
    params.equals(that.params);
 }
 
 @Override
 public int hashCode() {
  if (params == null) {
   return Objects.hash(beanName, methodName);
  }
 
  return Objects.hash(beanName, methodName, params);
 }
}

添加定時任務注冊類,用來增加、刪除定時任務。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@Component
public class CronTaskRegistrar implements DisposableBean {
 
 private final Map<Runnable, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>(16);
 
 @Autowired
 private TaskScheduler taskScheduler;
 
 public TaskScheduler getScheduler() {
  return this.taskScheduler;
 }
 
 public void addCronTask(Runnable task, String cronExpression) {
  addCronTask(new CronTask(task, cronExpression));
 }
 
 public void addCronTask(CronTask cronTask) {
  if (cronTask != null) {
   Runnable task = cronTask.getRunnable();
   if (this.scheduledTasks.containsKey(task)) {
    removeCronTask(task);
   }
 
   this.scheduledTasks.put(task, scheduleCronTask(cronTask));
  }
 }
 
 public void removeCronTask(Runnable task) {
  ScheduledTask scheduledTask = this.scheduledTasks.remove(task);
  if (scheduledTask != null)
   scheduledTask.cancel();
 }
 
 public ScheduledTask scheduleCronTask(CronTask cronTask) {
  ScheduledTask scheduledTask = new ScheduledTask();
  scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
 
  return scheduledTask;
 }
 
 
 @Override
 public void destroy() {
  for (ScheduledTask task : this.scheduledTasks.values()) {
   task.cancel();
  }
 
  this.scheduledTasks.clear();
 }
}

添加定時任務示例類

?
1
2
3
4
5
6
7
8
9
10
@Component("demoTask")
public class DemoTask {
 public void taskWithParams(String params) {
  System.out.println("執行有參示例任務:" + params);
 }
 
 public void taskNoParams() {
  System.out.println("執行無參示例任務");
 }
}

定時任務數據庫表設計

Spring Boot如何實現定時任務的動態增刪啟停詳解

定時任務數據庫表設計

添加定時任務實體類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class SysJobPO {
 
 private Integer jobId;
 
 private String beanName;
 
 private String methodName;
 
 private String methodParams;
 
 private String cronExpression;
 
 private Integer jobStatus;
 
 private String remark;
 
 private Date createTime;
 
 private Date updateTime;
 
 public Integer getJobId() {
  return jobId;
 }
 
 public void setJobId(Integer jobId) {
  this.jobId = jobId;
 }
 
 public String getBeanName() {
  return beanName;
 }
 
 public void setBeanName(String beanName) {
  this.beanName = beanName;
 }
 
 public String getMethodName() {
  return methodName;
 }
 
 public void setMethodName(String methodName) {
  this.methodName = methodName;
 }
 
 public String getMethodParams() {
  return methodParams;
 }
 
 public void setMethodParams(String methodParams) {
  this.methodParams = methodParams;
 }
 
 public String getCronExpression() {
  return cronExpression;
 }
 
 public void setCronExpression(String cronExpression) {
  this.cronExpression = cronExpression;
 }
 
 public Integer getJobStatus() {
  return jobStatus;
 }
 
 public void setJobStatus(Integer jobStatus) {
  this.jobStatus = jobStatus;
 }
 
 public String getRemark() {
  return remark;
 }
 
 public void setRemark(String remark) {
  this.remark = remark;
 }
 
 public Date getCreateTime() {
  return createTime;
 }
 
 public void setCreateTime(Date createTime) {
  this.createTime = createTime;
 }
 
 public Date getUpdateTime() {
  return updateTime;
 }
 
 public void setUpdateTime(Date updateTime) {
  this.updateTime = updateTime;
 }
}

新增定時任務

Spring Boot如何實現定時任務的動態增刪啟停詳解

新增定時任務

?
1
2
3
4
5
6
7
8
9
10
11
boolean success = sysJobRepository.addSysJob(sysJob);
if (!success)
 return OperationResUtils.fail("新增失敗");
else {
 if (sysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
  SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
  cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());
 }
}
 
return OperationResUtils.success();

修改定時任務,先移除原來的任務,再啟動新任務

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
boolean success = sysJobRepository.editSysJob(sysJob);
if (!success)
 return OperationResUtils.fail("編輯失敗");
else {
 
 if (existedSysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
  SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
  cronTaskRegistrar.removeCronTask(task);
 }
 
 if (sysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
  SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
  cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());
 }
}
 
return OperationResUtils.success();

刪除定時任務

?
1
2
3
4
5
6
7
8
9
10
11
boolean success = sysJobRepository.deleteSysJobById(req.getJobId());
if (!success)
 return OperationResUtils.fail("刪除失敗");
else{
 if (existedSysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
  SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
  cronTaskRegistrar.removeCronTask(task);
 }
}
 
return OperationResUtils.success();

定時任務啟動 / 停止狀態切換

?
1
2
3
4
5
6
7
if (existedSysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
 SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
 cronTaskRegistrar.addCronTask(task, existedSysJob.getCronExpression());
} else {
 SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
 cronTaskRegistrar.removeCronTask(task);
}

添加實現了 CommandLineRunner 接口的 SysJobRunner 類,當 spring boot 項目啟動完成后,加載數據庫里狀態為正常的定時任務。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Service
public class SysJobRunner implements CommandLineRunner {
 
 private static final Logger logger = LoggerFactory.getLogger(SysJobRunner.class);
 
 @Autowired
 private ISysJobRepository sysJobRepository;
 
 @Autowired
 private CronTaskRegistrar cronTaskRegistrar;
 
 @Override
 public void run(String... args) {
  
  List<SysJobPO> jobList = sysJobRepository.getSysJobListByStatus(SysJobStatus.NORMAL.ordinal());
  if (CollectionUtils.isNotEmpty(jobList)) {
   for (SysJobPO job : jobList) {
    SchedulingRunnable task = new SchedulingRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams());
    cronTaskRegistrar.addCronTask(task, job.getCronExpression());
   }
 
   logger.info("定時任務已加載完畢...");
  }
 }
}

工具類 SpringContextUtils,用來從 spring 容器里獲取 bean

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@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);
 }
}

總結

到此這篇關于Spring Boot如何實現定時任務的動態增刪啟停的文章就介紹到這了,更多相關SpringBoot定時任務的動態增刪啟停內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.geek521.com/2020/07/18/springboot實現定時任務的動態增刪啟停/

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品毛片一区二区三区 | 亚洲精品久久久久久下一站 | 中文字幕亚洲综合久久久软件 | 欧美综合一区 | 亚洲国产精品99久久久久久久久 | 视频一区在线观看 | www.av在线播放 | 国产第一毛片 | 久久av网 | 黄色中文字幕 | 国产精品ssss在线亚洲 | 黄色一级毛片a | 欧美黄色一区 | 精品成人网| 黄色影片免费在线观看 | 久久精品视频网站 | 国产四区| 欧洲亚洲精品久久久久 | 国产精品久久电影观看 | 久久免费公开视频 | 狠久久| 国产精品成人国产乱一区 | 欧美 日韩 中文字幕 | 久草中文在线观看 | 国产美女网站视频 | 欧美精品三区 | 中文字幕人成乱码在线观看 | 国产午夜精品一区二区三区 | 日韩国产欧美 | 日韩国产精品一区 | 日韩不卡一区二区三区 | 久久久久久久久国产 | 久久精品国产一区二区三区不卡 | 日本女人高潮视频 | 操av网| 自拍偷拍第一页 | 91精品国产综合久久香蕉的用户体验 | 国产一区在线视频 | 日韩一区二区三区视频 | 午夜高清视频 | 国产精品香蕉在线观看 |