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

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

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

服務器之家 - 編程語言 - Java教程 - Spring內置任務調度如何實現添加、取消與重置詳解

Spring內置任務調度如何實現添加、取消與重置詳解

2021-01-18 10:17蔣固金 Java教程

任務調度是我們日常開發中經常會碰到的,下面這篇文章主要給大家介紹了關于Spring內置任務調度如何實現添加、取消與重置的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學

前言

大家應該都有所體會,使用Spring任務調度給我們的開發帶來了極大的便利,不過當我們的任務調度配置完成后,很難再對其進行更改,除非停止服務器,修改配置,然后再重啟,顯然這樣是不利于線上操作的,為了實現動態的任務調度修改,我在網上也查閱了一些資料,大部分都是基于quartz實現的,使用Spring內置的任務調度則少之又少,而且效果不理想,需要在下次任務執行后,新的配置才能生效,做不到立即生效。本著探索研究的原則,查看了一下Spring的源碼,下面為大家提供一種Spring內置任務調度實現添加、取消、重置的方法。話不多說了,來一起看看詳細的介紹 吧。

實現方法如下

首先,我們需要啟用Spring的任務調度

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:task="http://www.springframework.org/schema/task"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.2.xsd
  http://www.springframework.org/schema/task
  http://www.springframework.org/schema/task/spring-task-3.2.xsd">
 <task:annotation-driven executor="jobExecutor" scheduler="jobScheduler" />
 <task:executor id="jobExecutor" pool-size="5"/>
 <task:scheduler id="jobScheduler" pool-size="10" />
</beans>

這一部分配置在網上是很常見的,接下來我們需要聯合使用@EnableScheduling與org.springframework.scheduling.annotation.SchedulingConfigurer便攜我們自己的調度配置,在SchedulingConfigurer接口中,需要實現一個void configureTasks(ScheduledTaskRegistrar taskRegistrar);方法,傳統做法是在該方法中添加需要執行的調度信息。網上的基本撒謊那個也都是使用該方法實現的,使用addTriggerTask添加任務,并結合cron表達式動態修改調度時間,這里我們并不這樣做。

查看一下ScheduledTaskRegistrar源碼,我們發現該對象初始化完成后會執行scheduleTasks()方法,在該方法中添加任務調度信息,最終所有的任務信息都存放在名為scheduledFutures的集合中。

?
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
protected void scheduleTasks() {
  long now = System.currentTimeMillis();
 
  if (this.taskScheduler == null) {
   this.localExecutor = Executors.newSingleThreadScheduledExecutor();
   this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
  }
  if (this.triggerTasks != null) {
   for (TriggerTask task : this.triggerTasks) {
    this.scheduledFutures.add(this.taskScheduler.schedule(
      task.getRunnable(), task.getTrigger()));
   }
  }
  if (this.cronTasks != null) {
   for (CronTask task : this.cronTasks) {
    this.scheduledFutures.add(this.taskScheduler.schedule(
      task.getRunnable(), task.getTrigger()));
   }
  }
  if (this.fixedRateTasks != null) {
   for (IntervalTask task : this.fixedRateTasks) {
    if (task.getInitialDelay() > 0) {
     Date startTime = new Date(now + task.getInitialDelay());
     this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
       task.getRunnable(), startTime, task.getInterval()));
    }
    else {
     this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
       task.getRunnable(), task.getInterval()));
    }
   }
  }
  if (this.fixedDelayTasks != null) {
   for (IntervalTask task : this.fixedDelayTasks) {
    if (task.getInitialDelay() > 0) {
     Date startTime = new Date(now + task.getInitialDelay());
     this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
       task.getRunnable(), startTime, task.getInterval()));
    }
    else {
     this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
       task.getRunnable(), task.getInterval()));
    }
   }
  }
 }

所以我的思路就是動態修改該集合,實現任務調度的添加、取消、重置。實現代碼如下:

?
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.jianggujin.web.util.job;
 
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
 
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
 
import com.jianggujin.web.util.BeanUtils;
 
/**
 * 默認任務調度配置
 *
 * @author jianggujin
 *
 */
@EnableScheduling
public class DefaultSchedulingConfigurer implements SchedulingConfigurer
{
 private final String FIELD_SCHEDULED_FUTURES = "scheduledFutures";
 private ScheduledTaskRegistrar taskRegistrar;
 private Set<ScheduledFuture<?>> scheduledFutures = null;
 private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();
 
 @Override
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
 {
  this.taskRegistrar = taskRegistrar;
 }
 
 @SuppressWarnings("unchecked")
 private Set<ScheduledFuture<?>> getScheduledFutures()
 {
  if (scheduledFutures == null)
  {
   try
   {
   scheduledFutures = (Set<ScheduledFuture<?>>) BeanUtils.getProperty(taskRegistrar, FIELD_SCHEDULED_FUTURES);
   }
   catch (NoSuchFieldException e)
   {
   throw new SchedulingException("not found scheduledFutures field.");
   }
  }
  return scheduledFutures;
 }
 
 /**
 * 添加任務
 *
 * @param taskId
 * @param triggerTask
 */
 public void addTriggerTask(String taskId, TriggerTask triggerTask)
 {
  if (taskFutures.containsKey(taskId))
  {
   throw new SchedulingException("the taskId[" + taskId + "] was added.");
  }
  TaskScheduler scheduler = taskRegistrar.getScheduler();
  ScheduledFuture<?> future = scheduler.schedule(triggerTask.getRunnable(), triggerTask.getTrigger());
  getScheduledFutures().add(future);
  taskFutures.put(taskId, future);
 }
 
 /**
 * 取消任務
 *
 * @param taskId
 */
 public void cancelTriggerTask(String taskId)
 {
  ScheduledFuture<?> future = taskFutures.get(taskId);
  if (future != null)
  {
   future.cancel(true);
  }
  taskFutures.remove(taskId);
  getScheduledFutures().remove(future);
 }
 
 /**
 * 重置任務
 *
 * @param taskId
 * @param triggerTask
 */
 public void resetTriggerTask(String taskId, TriggerTask triggerTask)
 {
  cancelTriggerTask(taskId);
  addTriggerTask(taskId, triggerTask);
 }
 
 /**
 * 任務編號
 *
 * @return
 */
 public Set<String> taskIds()
 {
  return taskFutures.keySet();
 }
 
 /**
 * 是否存在任務
 *
 * @param taskId
 * @return
 */
 public boolean hasTask(String taskId)
 {
  return this.taskFutures.containsKey(taskId);
 }
 
 /**
 * 任務調度是否已經初始化完成
 *
 * @return
 */
 public boolean inited()
 {
  return this.taskRegistrar != null && this.taskRegistrar.getScheduler() != null;
 }
}

其中用到的BeanUtils源碼如下:

?
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.jianggujin.web.util;
 
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class BeanUtils
{
 
 public static Field findField(Class<?> clazz, String name)
 {
  try
  {
   return clazz.getField(name);
  }
  catch (NoSuchFieldException ex)
  {
   return findDeclaredField(clazz, name);
  }
 }
 
 public static Field findDeclaredField(Class<?> clazz, String name)
 {
  try
  {
   return clazz.getDeclaredField(name);
  }
  catch (NoSuchFieldException ex)
  {
   if (clazz.getSuperclass() != null)
   {
   return findDeclaredField(clazz.getSuperclass(), name);
   }
   return null;
  }
 }
 
 public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
 {
  try
  {
   return clazz.getMethod(methodName, paramTypes);
  }
  catch (NoSuchMethodException ex)
  {
   return findDeclaredMethod(clazz, methodName, paramTypes);
  }
 }
 
 public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
 {
  try
  {
   return clazz.getDeclaredMethod(methodName, paramTypes);
  }
  catch (NoSuchMethodException ex)
  {
   if (clazz.getSuperclass() != null)
   {
   return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
   }
   return null;
  }
 }
 
 public static Object getProperty(Object obj, String name) throws NoSuchFieldException
 {
  Object value = null;
  Field field = findField(obj.getClass(), name);
  if (field == null)
  {
   throw new NoSuchFieldException("no such field [" + name + "]");
  }
  boolean accessible = field.isAccessible();
  field.setAccessible(true);
  try
  {
   value = field.get(obj);
  }
  catch (Exception e)
  {
   throw new RuntimeException(e);
  }
  field.setAccessible(accessible);
  return value;
 }
 
 public static void setProperty(Object obj, String name, Object value) throws NoSuchFieldException
 {
  Field field = findField(obj.getClass(), name);
  if (field == null)
  {
   throw new NoSuchFieldException("no such field [" + name + "]");
  }
  boolean accessible = field.isAccessible();
  field.setAccessible(true);
  try
  {
   field.set(obj, value);
  }
  catch (Exception e)
  {
   throw new RuntimeException(e);
  }
  field.setAccessible(accessible);
 }
 
 public static Map<String, Object> obj2Map(Object obj, Map<String, Object> map)
 {
  if (map == null)
  {
   map = new HashMap<String, Object>();
  }
  if (obj != null)
  {
   try
   {
   Class<?> clazz = obj.getClass();
   do
   {
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields)
    {
     int mod = field.getModifiers();
     if (Modifier.isStatic(mod))
     {
      continue;
     }
     boolean accessible = field.isAccessible();
     field.setAccessible(true);
     map.put(field.getName(), field.get(obj));
     field.setAccessible(accessible);
    }
    clazz = clazz.getSuperclass();
   } while (clazz != null);
   }
   catch (Exception e)
   {
   throw new RuntimeException(e);
   }
  }
  return map;
 }
 
 /**
 * 獲得父類集合,包含當前class
 *
 * @param clazz
 * @return
 */
 public static List<Class<?>> getSuperclassList(Class<?> clazz)
 {
  List<Class<?>> clazzes = new ArrayList<Class<?>>(3);
  clazzes.add(clazz);
  clazz = clazz.getSuperclass();
  while (clazz != null)
  {
   clazzes.add(clazz);
   clazz = clazz.getSuperclass();
  }
  return Collections.unmodifiableList(clazzes);
 }
}

因為加載的延遲,在使用這種方法自定義配置任務調度是,首先需要調用inited()方法判斷是否初始化完成,否則可能出現錯誤。

接下來我們來測試一下:

?
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
package com.jianggujin.zft.job;
 
import java.util.Calendar;
 
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
 
import com.jianggujin.web.util.job.DefaultSchedulingConfigurer;
 
public class TestJob implements InitializingBean
{
 @Autowired
 private DefaultSchedulingConfigurer defaultSchedulingConfigurer;
 
 public void afterPropertiesSet() throws Exception
 {
  new Thread() {
   public void run()
   {
 
   try
   {
    // 等待任務調度初始化完成
    while (!defaultSchedulingConfigurer.inited())
    {
     Thread.sleep(100);
    }
   }
   catch (InterruptedException e)
   {
    e.printStackTrace();
   }
   System.out.println("任務調度初始化完成,添加任務");
   defaultSchedulingConfigurer.addTriggerTask("task", new TriggerTask(new Runnable() {
 
    @Override
    public void run()
    {
     System.out.println("run job..." + Calendar.getInstance().get(Calendar.SECOND));
 
    }
   }, new CronTrigger("0/5 * * * * ? ")));
   };
  }.start();
  new Thread() {
   public void run()
   {
 
   try
   {
    Thread.sleep(30000);
   }
   catch (Exception e)
   {
   }
   System.out.println("重置任務............");
   defaultSchedulingConfigurer.resetTriggerTask("task", new TriggerTask(new Runnable() {
 
    @Override
    public void run()
    {
     System.out.println("run job..." + Calendar.getInstance().get(Calendar.SECOND));
 
    }
   }, new CronTrigger("0/10 * * * * ? ")));
   };
  }.start();
 }
}

在該類中,我們首先使用一個線程,等待我們自己的任務調度初始化完成后向其中添加一個每五秒鐘打印一句話的任務,然后再用另一個線程過30秒后修改該任務,修改的本質其實是現將原來的任務取消,然后再添加一個新的任務。

在配置文件中初始化上面的類

?
1
2
<bean id="defaultSchedulingConfigurer" class="com.jianggujin.web.util.job.DefaultSchedulingConfigurer"/>
<bean id="testJob" class="com.jianggujin.zft.job.TestJob"/>

運行程序,觀察控制臺輸出

Spring內置任務調度如何實現添加、取消與重置詳解

這樣我們就實現了動態的重置任務了。以上為個人探索出來的方法,如有更好的解決方案,歡迎指正。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://blog.csdn.net/jianggujin/article/details/77937316

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲小视频 | 中文字幕av在线播放 | 国产精品亚洲一区 | 欧美激情一区二区 | 在线中文字幕视频 | 亚洲国产精品久久久久久久久久久 | 亚洲国产aⅴ成人精品无吗 黄色免费在线看 | 亚洲+变态+欧美+另类+精品 | 中文字幕在线观看 | 中文字幕在线观看第一页 | 最近中文字幕mv免费高清在线 | 中文字幕国产视频 | 国产精品区二区三区日本 | 国产伊人久| 日本成人一区 | www.一区 | 欧美a级成人淫片免费看 | 国产精品一区在线 | 亚洲精品久久久久久久久久久 | 亚洲三级在线观看 | 男人的天堂午夜 | 欧美成视频 | 亚洲a网| 国产情侣免费视频 | 黑人精品| 欧美成人a | 国产亚洲综合一区二区 | 狠狠色综合网站久久久久久久 | 三级视频在线观看 | 在线亚洲精品 | 久久久久久久久久久网站 | 一区二区不卡视频 | 韩国av一区二区 | 成人网免费看 | 久久精品1区 | 日韩在线看片 | 新91在线 | 久久视频免费 | 日韩欧美在线一区 | 日韩中文字幕在线 | 欧美日韩激情一区 |