激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - Java定時(shí)任務(wù)詳解

Java定時(shí)任務(wù)詳解

2020-09-20 14:18wuzhiyuan Java教程

定時(shí)任務(wù)在項(xiàng)目中經(jīng)常會(huì)使用到,本文主要根據(jù)博主自己使用定時(shí)的經(jīng)驗(yàn)分如下幾點(diǎn)介紹定時(shí)任務(wù):1、Quartz定時(shí)任務(wù)簡介及Spring配置Quartz定時(shí)任務(wù);2、SchedulerFactory對定時(shí)任務(wù)進(jìn)行增刪改查

定時(shí)任務(wù)在項(xiàng)目中經(jīng)常會(huì)使用到,本文主要根據(jù)博主自己使用定時(shí)的經(jīng)驗(yàn)分如下幾點(diǎn)介紹定時(shí)任務(wù):

1、Quartz定時(shí)任務(wù)簡介及Spring配置Quartz定時(shí)任務(wù)

2、SchedulerFactory對定時(shí)任務(wù)進(jìn)行增刪改查

3、總結(jié)

Quartz定時(shí)任務(wù)簡介:

Quartz是項(xiàng)目中經(jīng)常用到的定時(shí)任務(wù)之一,是一個(gè)完全由java編寫的開源作業(yè)調(diào)度框架,可以與J2EE與J2SE應(yīng)用程序相結(jié)合也可以單獨(dú)使用,其主要組成部分包括Job、Scheduler、CronExpression,這里就不一一介紹了,下面介紹Spring如何配置Quartz。

配置Quartz需要明白的一點(diǎn)是配置Quartz即配置Job、Scheduler和CronExpression,這三部分配置完成后,就是一個(gè)完整的定時(shí)任務(wù),配置如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<bean id= "TestJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
  <property name="jobClass" value="xx.TestQuartzJob"/>
  <!-- 可以封裝各種數(shù)據(jù)到JobExecutionContext里,包括接口、類,其中testServiceImpl是Spring管理的Bean,需要什么聲明 -->
  <property name="jobDataAsMap">
    <map>
      <entry key="test" value="test"/>
      <entry key ="testServiceImpl" value-ref="testServiceImpl"/>
    </map>
  </property>
</bean>
 
<bean id= "TestTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail" ref="TestJobDetail" />
  <property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
 
<bean id= "testSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers" >
    <list>
      <ref bean="TestTrigger" />
    </list>
  </property>
</bean>
<bean id="testServiceImpl" class="xx.service.impl.TestServiceImpl">

配置完成后,就是增加一個(gè)為你執(zhí)行一個(gè)任務(wù)的Java類。每一個(gè)Quartz Job必須有一個(gè) 實(shí)現(xiàn)了org.quartz.Job接口的具體類,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TestQuartzJob extends QuartzJobBean {
  @Override
  protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException
  {
    // 獲取Job配置的接口
    TestServiceImpl testServiceImpl = (TestServiceImpl) arg0.getJobDetail().getJobDataMap().get("testServiceImpl");
    // 執(zhí)行業(yè)務(wù)方法
    quartzStart();
  }
  public void quartzStart(){
    // 業(yè)務(wù)方法...
  }
}

當(dāng)然,在Job中其實(shí)不用特意的配置接口,使用Spring的注入即可,這里只是把這個(gè)配置接口的方法進(jìn)行說明。

到這里,簡單的配置Quartz定時(shí)任務(wù)已經(jīng)完成,下面附加一個(gè)我在項(xiàng)目中使用Quartz的情形:cronExpression表達(dá)式從數(shù)據(jù)庫讀取。

當(dāng)時(shí),我解決這個(gè)問題的方法是繼承org.springframework.scheduling.quartz.CronTriggerBean,設(shè)置cronExpression,具體代碼如下:

Trigger的配置要改:

?
1
2
3
4
<bean id="TestTrigger" class="xx.InitCronTriggerFactoryBean">
  <property name="jobDetail" ref="TestJobDetail" />
  <property name="key" value="key" />
</bean>

xx.InitCronTriggerFactoryBean代碼:

?
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
public class InitCronTriggerFactoryBean extends CronTriggerFactoryBean implements Serializable {
 
  private static final long serialVersionUID = 1L;
 
  @Resource
  private SysParamService sysParamService;
 
  private String key;
 
  public void setKey(String key)
  {
    this.key = key;
 
    setCronExpression(getCronExpressionFromDB());
  }
 
  private String getCronExpressionFromDB()
  {
    if(StringUtils.isEmpty(key))
      return "0 0/5 * * * ?";
 
    SysParam sysParam = new SysParam();
 
    try
    {
      sysParam = sysParamService.getNameByKey(key);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
 
    if(sysParam != null && !StringUtils.isEmpty(sysParam.getParamValue()))
      return sysParam.getParamValue();
 
    return "0 0/5 * * * ?";
  }
}

其中,SysParamService是根據(jù)key到數(shù)據(jù)庫查詢對應(yīng)的cronExpression表達(dá)式的接口,這個(gè)接口除了使用Spring注入,也可以使用set方法設(shè)置,如下:

?
1
2
3
4
5
6
<bean id="TestTrigger" class="xx.InitCronTriggerFactoryBean">
  <property name="jobDetail" ref="TestJobDetail" />
  <property name="key" value="key" />
  <property name="sysParamService" ref="sysParamService" />
</bean>
<bean id="sysParamService" class="xx.service.impl.SysParamServiceImpl">

這樣,在xx.InitCronTriggerFactoryBean就要加入sysParamService的set方法,此時(shí)的xx.InitCronTriggerFactoryBean代碼為:

?
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
public class InitCronTriggerFactoryBean extends CronTriggerFactoryBean implements Serializable {
  private static final long serialVersionUID = 1L;
  private SysParamServiceImpl sysParamService;
  private String key;
  public void setKey(String key)
  {
    this.key = key;
  }
  public void setSysParamService(SysParamServiceImpl sysParamService)
  {
    this.sysParamService = sysParamService;
    setCronExpression(getCronExpressionFromDB());
  }
  private String getCronExpressionFromDB()
  {
    if(StringUtils.isEmpty(key))
      return "0 0 0/1 * * ?";
    SysParam sysParam = new SysParam();
    try
    {
      sysParam = sysParamServiceImpl.getNameByKey(key);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    if(sysParam != null && !StringUtils.isEmpty(sysParam.getParamValue()))
      return sysParam.getParamValue();
    return "0 0 0/1 * * ?";
  }
}

Quartz定時(shí)任務(wù)到這里就差不多了,基本的配置和使用就是上面將的,想要深入了解Quartz可以在網(wǎng)上查找更多的資料,并在實(shí)踐中使用。接下來將講解在項(xiàng)目中使用的可以隨時(shí)對定時(shí)任務(wù)進(jìn)行增刪改查操作的實(shí)例。

定時(shí)任務(wù)的增刪改查,其實(shí)可以看做是對數(shù)據(jù)進(jìn)行增刪改查。不過,定時(shí)任務(wù)的增刪改查是操作Job和Trigger,具體代碼如下:

定時(shí)任務(wù)管理器代碼:

?
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
public class QuartzManager {
 
  private static final Logger logger = LogPresident.getRootLogger();
 
  private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
 
  private static Map<String, JobKey> jobKeyMap = new HashMap<String, JobKey>();
 
  /**
  * 增加一個(gè)定時(shí)任務(wù)
  * @author zhiyuan.wu
  * @date 2017年3月30日
  * @param jobName
  * @param triggerName
  * @param cls
  * @param date
  */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static void addJob(String jobName, String triggerName, Class cls, Date date)
  {
    try
    {
      Scheduler scheduler = schedulerFactory.getScheduler();
 
      // job
      JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, Scheduler.DEFAULT_GROUP).build();
 
      // 觸發(fā)器
      SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(triggerName, Scheduler.DEFAULT_GROUP).startAt(date).build();
 
      scheduler.scheduleJob(jobDetail, trigger);
 
      // 啟動(dòng)
      scheduler.start();
 
      jobKeyMap.put(jobDetail.getKey().getName(), jobDetail.getKey());
    }
    catch (Exception e)
    {
      logger.error("--------添加定時(shí)任務(wù)出錯(cuò):" + e.getMessage(), e);
    }
  }
 
/**
* 刪除對應(yīng)的定時(shí)任務(wù)
* @author zhiyuan.wu
* @date 2017年3月29日
* @param jobKey
*/
public static void removeJob(JobKey jobKey)
{
  Scheduler scheduler;
  try
  {
    scheduler = schedulerFactory.getScheduler();
    scheduler.deleteJob(jobKey);
 
      jobKeyMap.remove(jobKey.getName());
    }
    catch (SchedulerException e)
    {
      logger.error("--------刪除定時(shí)任務(wù)出錯(cuò):" + e.getMessage(), e);
    }
  }
 
/**
* 啟動(dòng)所有定時(shí)任務(wù)
* @author zhiyuan.wu
* @date 2017年3月29日
*/
public static void startJobs()
{
  try
  {
    Scheduler sched = schedulerFactory.getScheduler();
    sched.start();
  }
  catch (Exception e)
  {
    logger.error("--------啟動(dòng)所有定時(shí)任務(wù)出錯(cuò):" + e.getMessage(), e);
  }
}
 
/**
* 停止所有定時(shí)任務(wù)
* @author zhiyuan.wu
* @date 2017年3月29日
*/
public static void shutdownJobs()
{
  try
  {
    Scheduler sched = schedulerFactory.getScheduler();
 
    if (!sched.isShutdown())
    {
      sched.shutdown();
    }
  }
  catch (Exception e)
  {
    logger.error("--------停止所有定時(shí)任務(wù)出錯(cuò):" + e.getMessage(), e);
  }
}
 
/**
* 修改定時(shí)任務(wù)
* @author zhiyuan.wu
* @date 2017年3月29日
* @param jobKey
* @param jobName
* @param triggerName
* @param cls
* @param date
*/
@SuppressWarnings("rawtypes")
public static void modifyJobTime(JobKey jobKey, String jobName, String triggerName, Class cls, Date date)
{
  try
  {
    removeJob(jobKey);
 
    addJob(jobName, triggerName, cls, date);
  }
  catch (Exception e)
  {
    logger.error("--------修改定時(shí)任務(wù)出錯(cuò):" + e.getMessage(), e);
  }
}
 
/**
* 打印當(dāng)前定時(shí)任務(wù)的jobName
* @author zhiyuan.wu
* @date 2017年3月29日
* @throws SchedulerException
*/
public static void printJobName() throws SchedulerException
{
  for (String jobName : jobKeyMap.keySet())
  {
    logger.info("--------jobName:" + jobName);
  }
}
}

Job代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestJob implements Job {
 
  private static final Logger logger = LogPresident.getRootLogger();
 
  public void execute(JobExecutionContext context) throws JobExecutionException
  {
    JobKey jobKey = context.getJobDetail().getKey();
 
    logger.info("--------定時(shí)任務(wù)開始執(zhí)行:" + jobKey.getName());
 
    // 業(yè)務(wù)方法...
    // 移除定時(shí)任務(wù)
    QuartzManager.removeJob(jobKey);
  }
}

增加一個(gè)定時(shí)任務(wù)代碼:

QuartzManager.addJob(JobName, TriggerName , TestJob.class, Date);

這樣,在到達(dá)時(shí)間Date時(shí),定時(shí)任務(wù)將會(huì)執(zhí)行。不過這樣增加的任務(wù)是保存在內(nèi)存中,項(xiàng)目重啟將會(huì)丟失定時(shí)任務(wù),所以,最好增加一個(gè)類,在項(xiàng)目啟動(dòng)時(shí)將會(huì)掃描數(shù)據(jù)庫,將未執(zhí)行的定時(shí)任務(wù)重新加載到內(nèi)存中去。

定時(shí)任務(wù)在項(xiàng)目中運(yùn)用需要根據(jù)業(yè)務(wù)具體調(diào)整,但只要弄清楚定時(shí)任務(wù)的原理和實(shí)現(xiàn),那么就可以在項(xiàng)目中靈活運(yùn)它用來具體的業(yè)務(wù),希望這篇文章可以讓大家快速了解和運(yùn)用定時(shí)任務(wù),并運(yùn)用到實(shí)踐中。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持服務(wù)器之家!

原文鏈接:http://www.cnblogs.com/wuzhiyuan/p/6773254.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产午夜三级一区二区三桃花影视 | 欧美一级精品片在线看 | 欧美日韩一 | av噜噜在线| 亚洲精品日韩欧美 | 在线中文字幕亚洲 | 久久久久久久久浪潮精品 | 少妇一级淫片免费看 | 日日草天天干 | 一区二区三区视频在线 | 成人短视频在线观看 | 欧美一区二区三区不卡免费观看 | 蜜桃网站在线 | 青青草成人av | 禁漫天堂久久久久久久久久 | 国产视频在线观看一区二区三区 | 国产69精品久久久久久 | 亚洲尻逼视频 | 国产91精品久久久 | 久久影院一区二区三区 | 毛片网站网址 | 久久精品一级片 | 色播亚洲 | 毛片大全 | 国产精品久久久久久模特 | 二级大黄大片高清在线视频 | 黄色网欧美 | 在线观看国产免费视频 | 性高跟鞋xxxxhd4kvideos | 国产高潮国产高潮久久久91 | 日韩一级精品 | 国产一区二区三区四区五区在线 | 欧美日韩精品一区二区三区不卡 | 中文字幕 日本 | 国产无遮挡一区二区三区毛片日本 | 欧美成人影院 | 欧美人一级淫片a免费播放 久久99精品久久久久久园产越南 | 九草在线| 一区二区三区视频在线播放 | 国产人成精品综合欧美成人 | 一区二区精品在线 |