一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - Java定時任務詳解

Java定時任務詳解

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

定時任務在項目中經常會使用到,本文主要根據博主自己使用定時的經驗分如下幾點介紹定時任務:1、Quartz定時任務簡介及Spring配置Quartz定時任務;2、SchedulerFactory對定時任務進行增刪改查

定時任務在項目中經常會使用到,本文主要根據博主自己使用定時的經驗分如下幾點介紹定時任務:

1、Quartz定時任務簡介及Spring配置Quartz定時任務

2、SchedulerFactory對定時任務進行增刪改查

3、總結

Quartz定時任務簡介:

Quartz是項目中經常用到的定時任務之一,是一個完全由java編寫的開源作業調度框架,可以與J2EE與J2SE應用程序相結合也可以單獨使用,其主要組成部分包括Job、Scheduler、CronExpression,這里就不一一介紹了,下面介紹Spring如何配置Quartz。

配置Quartz需要明白的一點是配置Quartz即配置Job、Scheduler和CronExpression,這三部分配置完成后,就是一個完整的定時任務,配置如下:

?
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"/>
  <!-- 可以封裝各種數據到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">

配置完成后,就是增加一個為你執行一個任務的Java類。每一個Quartz Job必須有一個 實現了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");
    // 執行業務方法
    quartzStart();
  }
  public void quartzStart(){
    // 業務方法...
  }
}

當然,在Job中其實不用特意的配置接口,使用Spring的注入即可,這里只是把這個配置接口的方法進行說明。

到這里,簡單的配置Quartz定時任務已經完成,下面附加一個我在項目中使用Quartz的情形:cronExpression表達式從數據庫讀取。

當時,我解決這個問題的方法是繼承org.springframework.scheduling.quartz.CronTriggerBean,設置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是根據key到數據庫查詢對應的cronExpression表達式的接口,這個接口除了使用Spring注入,也可以使用set方法設置,如下:

?
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方法,此時的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定時任務到這里就差不多了,基本的配置和使用就是上面將的,想要深入了解Quartz可以在網上查找更多的資料,并在實踐中使用。接下來將講解在項目中使用的可以隨時對定時任務進行增刪改查操作的實例。

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

定時任務管理器代碼:

?
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>();
 
  /**
  * 增加一個定時任務
  * @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();
 
      // 觸發器
      SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(triggerName, Scheduler.DEFAULT_GROUP).startAt(date).build();
 
      scheduler.scheduleJob(jobDetail, trigger);
 
      // 啟動
      scheduler.start();
 
      jobKeyMap.put(jobDetail.getKey().getName(), jobDetail.getKey());
    }
    catch (Exception e)
    {
      logger.error("--------添加定時任務出錯:" + e.getMessage(), e);
    }
  }
 
/**
* 刪除對應的定時任務
* @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("--------刪除定時任務出錯:" + e.getMessage(), e);
    }
  }
 
/**
* 啟動所有定時任務
* @author zhiyuan.wu
* @date 2017年3月29日
*/
public static void startJobs()
{
  try
  {
    Scheduler sched = schedulerFactory.getScheduler();
    sched.start();
  }
  catch (Exception e)
  {
    logger.error("--------啟動所有定時任務出錯:" + e.getMessage(), e);
  }
}
 
/**
* 停止所有定時任務
* @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("--------停止所有定時任務出錯:" + e.getMessage(), e);
  }
}
 
/**
* 修改定時任務
* @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("--------修改定時任務出錯:" + e.getMessage(), e);
  }
}
 
/**
* 打印當前定時任務的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("--------定時任務開始執行:" + jobKey.getName());
 
    // 業務方法...
    // 移除定時任務
    QuartzManager.removeJob(jobKey);
  }
}

增加一個定時任務代碼:

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

這樣,在到達時間Date時,定時任務將會執行。不過這樣增加的任務是保存在內存中,項目重啟將會丟失定時任務,所以,最好增加一個類,在項目啟動時將會掃描數據庫,將未執行的定時任務重新加載到內存中去。

定時任務在項目中運用需要根據業務具體調整,但只要弄清楚定時任務的原理和實現,那么就可以在項目中靈活運它用來具體的業務,希望這篇文章可以讓大家快速了解和運用定時任務,并運用到實踐中。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 3d蒂法精品啪啪一区二区免费 | 精品国产精品人妻久久无码五月天 | 色综合天天网 | 免费91麻豆精品国产自产在线观看 | 欧洲第一区第二区第三区 | 欧美精品v欧洲高清 | 九九99香蕉在线视频美国毛片 | 色综合久久综合网欧美综合网 | 免费人成在线观看视频播放 | 99久久精品免费看国产一区二区 | 欧美破苞合集 magnet | 超级碰碰青草免费视频92 | 国产在线视频在线观看 | 国产首页精品 | 九九精品成人免费国产片 | 99热免费在线 | 国产91精品久久久久久久 | 无码精品AV久久久奶水 | 国产日韩欧美成人 | 色人阁导航 | 女教师波多野结衣高清在线 | 国产精品一区二区三区免费 | 搞逼综合网 | 麻豆最新地址 | 9420高清完整版在线观看国语 | 成人看的羞羞视频免费观看 | 操爽| 美女用手扒开粉嫩的屁股 | 欧美精品一区二区在线观看 | 潘甜甜在线观看 | 成人aaaa| 91欧洲在线视精品在亚洲 | 欧美日韩视频在线成人 | 免费aⅴ片| 日韩成本大片35分钟免费播放 | 国产美女在线一区二区三区 | 国产精品久久久久久久久免费hd | 好姑娘在线观看完整版免费 | 亚洲无总热门 | 人人爱天天做夜夜爽88 | 深夜在线|