前言
今天收到一封郵件,大概內(nèi)容如下:spring boot鼓勵(lì)去配置化,那么怎么將第三方jar包中的xml去配置化了?
其實(shí),這個(gè)問(wèn)題,在前面的文章中也有提到,http://www.zmynmublwnt.cn/article/133145.html
下面,我們就以Quartz定時(shí)任務(wù)為例,單獨(dú)對(duì)這個(gè)問(wèn)題來(lái)進(jìn)行說(shuō)明,如何實(shí)現(xiàn)去配置化。
如果不使用spring boot,我們配置一個(gè)簡(jiǎn)單的定時(shí)任務(wù)時(shí),需要引入以下配置文件:
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
|
<!-- 配置需要定時(shí)執(zhí)行的任務(wù)類以及方法 --> < bean id = "doJob" class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" > <!-- 指定任務(wù)類 --> < property name = "targetObject" ref = "schedulerTask" /> <!-- 指定任務(wù)執(zhí)行的方法 --> < property name = "targetMethod" value = "doTask" /> < property name = "concurrent" value = "false" ></ property > </ bean > <!-- 配置觸發(fā)器 --> < bean id = "jobTrigger" class = "org.springframework.scheduling.quartz.CronTriggerFactoryBean" > < property name = "jobDetail" ref = "doJob" /> <!-- 每5秒運(yùn)行一次 --> < property name = "cronExpression" value = "0/5 * * * * ?" /> </ bean > <!-- 觸發(fā)定時(shí)任務(wù) --> < bean id = "schedulerFactoryBean" class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" > < property name = "triggers" > < list > < ref bean = "jobTrigger" /> <!-- 此處可以配置多個(gè)觸發(fā)器 --> </ list > </ property > < property name = "applicationContextSchedulerContextKey" value = "applicationContextKey" /> < property name = "waitForJobsToCompleteOnShutdown" value = "true" ></ property > </ bean > |
接下來(lái)的任務(wù),就是如何將上面的xml配置文件,去配置化。
從上面的配置文件中,可以得出,我們需要配置3個(gè)實(shí)例,分別是JobDetail,JobTrigger和Scheduler。
1、首先抽取出需要在application.properties配置文件中配置的屬性項(xiàng),從上面的配置文件中,可以得出如下需要配置的屬性項(xiàng),對(duì)應(yīng)的VO如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.chhliu.springboot.quartz.config; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties (prefix= "quartz.config" ) public class QuartzConfigProperties { private String targetObject; private String targetMethod; private boolean concurrent; private String cronExpression; private String applicationContextSchedulerContextKey; private boolean waitForJobsToCompleteOnShutdown; ……省略getter、setter方法…… } |
2、在application.properties配置文件中,加入如下配置
1
2
3
4
5
6
|
quartz.config.targetObject=taskJob ## 待執(zhí)行對(duì)象的名字 quartz.config.targetMethod=doJob ## 待執(zhí)行的方法的名字 quartz.config.concurrent=false ## 是否并發(fā),如果上一個(gè)定時(shí)任務(wù)還沒(méi)有執(zhí)行完,又被觸發(fā)了,如果配置為false,則需等待上個(gè)任務(wù)執(zhí)行完,才觸發(fā) quartz.config.cronExpression=0/5 * * * * ? ## 任務(wù)觸發(fā)表達(dá)式 quartz.config.applicationContextSchedulerContextKey=applicationContextKey ## 通過(guò)該key可以獲取spring上下文 quartz.config.waitForJobsToCompleteOnShutdown=true ## 是否等待任務(wù)完全執(zhí)行完后,再銷(xiāo)毀線程池 |
3、分別實(shí)例化JobDetail,JobTrigger和Scheduler
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
|
package com.chhliu.springboot.quartz.entity; import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import com.chhliu.springboot.quartz.config.QuartzConfigProperties; /** * 描述:將quartz的xml配置文件去配置化 * @author chhliu * 創(chuàng)建時(shí)間:2017年4月11日 下午7:41:21 * @version 1.2.0 */ @Configuration public class QuartzConfig { @Autowired private QuartzConfigProperties properties; // 注入屬性配置文件對(duì)應(yīng)的類實(shí)例 /** * attention: * Details:初始化JobDetail * @author chhliu * 創(chuàng)建時(shí)間:2017年4月11日 下午6:17:06 * @param task * @return * MethodInvokingJobDetailFactoryBean * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ @Bean (name = "jobDetail" ) public MethodInvokingJobDetailFactoryBean detailFactoryBean() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // ScheduleTask為需要執(zhí)行的任務(wù) MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); /* * 是否并發(fā)執(zhí)行 * 例如每5s執(zhí)行一次任務(wù),但是當(dāng)前任務(wù)還沒(méi)有執(zhí)行完,就已經(jīng)過(guò)了5s了, * 如果此處為true,則下一個(gè)任務(wù)會(huì)執(zhí)行,如果此處為false,則下一個(gè)任務(wù)會(huì)等待上一個(gè)任務(wù)執(zhí)行完后,再開(kāi)始執(zhí)行 */ jobDetail.setConcurrent(properties.isConcurrent()); /* * 為需要執(zhí)行的實(shí)體類對(duì)應(yīng)的對(duì)象 */ String targetObject = properties.getTargetObject(); jobDetail.setTargetBeanName(targetObject); /* * 通過(guò)這幾個(gè)配置,告訴JobDetailFactoryBean我們需要定時(shí)執(zhí)行targetObject類中的properties.getTargetMethod()方法 */ jobDetail.setTargetMethod(properties.getTargetMethod()); return jobDetail; } /** * attention: * Details:實(shí)例化JobTrigger * @author chhliu * 創(chuàng)建時(shí)間:2017年4月11日 下午7:39:14 * @param jobDetail * @return * CronTriggerFactoryBean */ @Bean(name = "jobTrigger") public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { CronTriggerFactoryBean tigger = new CronTriggerFactoryBean(); tigger.setJobDetail(jobDetail.getObject()); tigger.setCronExpression(properties.getCronExpression()); return tigger; } /** * attention: * Details:實(shí)例化Scheduler * @author chhliu * 創(chuàng)建時(shí)間:2017年4月11日 下午7:39:35 * @param cronJobTrigger * @return * SchedulerFactoryBean */ @Bean (name = "scheduler" ) public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) { SchedulerFactoryBean bean = new SchedulerFactoryBean(); // 注冊(cè)觸發(fā)器 bean.setTriggers(cronJobTrigger); // 通過(guò)applicationContextSchedulerContextKey屬性配置獲取spring上下文 bean.setApplicationContextSchedulerContextKey(properties.getApplicationContextSchedulerContextKey()); // 關(guān)閉任務(wù)的時(shí)候,是否等待任務(wù)執(zhí)行完畢 bean.setWaitForJobsToCompleteOnShutdown(properties.isWaitForJobsToCompleteOnShutdown()); return bean; } } |
4、編寫(xiě)需要執(zhí)行的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.chhliu.springboot.quartz.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @Service ( "taskJob" ) public class TaskJob { private static final Logger LOGGER = LoggerFactory.getLogger(TaskJob. class ); public void doJob(){ LOGGER.info( "hello spring boot, i'm the king of the world!!!" ); } } |
5、測(cè)試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.chhliu.springboot.quartz; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import com.chhliu.springboot.quartz.config.QuartzConfigProperties; @SpringBootApplication @EnableConfigurationProperties ({QuartzConfigProperties. class } ) // 開(kāi)啟配置屬性支持 public class SpringbootQuartzApplication { public static void main(String[] args) { SpringApplication.run(SpringbootQuartzApplication. class , args); } } |
6、測(cè)試結(jié)果如下
1
2
3
4
5
6
7
|
2017-04-11 19:09:35.017 INFO 7500 --- [eduler_Worker-1] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:09:40.004 INFO 7500 --- [eduler_Worker-2] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:09:45.004 INFO 7500 --- [eduler_Worker-3] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:09:50.004 INFO 7500 --- [eduler_Worker-4] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:09:55.001 INFO 7500 --- [eduler_Worker-5] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:10:00.002 INFO 7500 --- [eduler_Worker-6] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! 2017-04-11 19:10:05.001 INFO 7500 --- [eduler_Worker-7] c.chhliu.springboot.quartz.job.TaskJob : hello spring boot, i'm the king of the world!!! |
從上面的測(cè)試結(jié)果可以看出,任務(wù)被觸發(fā)了,也得到了正確的結(jié)果。
上面的這個(gè)示例,只是一個(gè)簡(jiǎn)單的例子,但是生產(chǎn)上復(fù)雜的需求,原理也是類似的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://blog.csdn.net/liuchuanhong1/article/details/70105193