您好,登錄后才能下訂單哦!
這篇文章主要講解了“java中怎么實現即時Quartz Job注入Bean”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java中怎么實現即時Quartz Job注入Bean”吧!
現今Spring已經成為企業級應用開發的事實框架,由于即時Quartz Job一般情況下不是Spring Bean,此時Job中就需要想辦法獲取Bean。
即時Job區別于周期/定時Job,是根據業務需要隨時提交的Quartz Job,常見于界面提交后臺的耗時任務(例如:導入/導出)。
接下來先簡單看一下幾種獲取Spring Bean的方式:
第一種:定義AppCtxUtils工具類,用于獲取Bean。
@Component public class AppCtxUtils implements ApplicationContextAware { private static ApplicationContext appCtx; @Override public void setApplicationContext(ApplicationContext appCtx) throws BeansException { this.appCtx = appCtx; } public static ApplicationContext getAppCtx() { return appCtx; } public static <T> T getBean(Class<T> clazz) { return appCtx.getBean(clazz); } public static <T> T getBean(String beanName) { return (T) appCtx.getBean(beanName); } }
public class AppCtxUtilsExampleJob implements Job { private ExampleService exampleService = AppCtxUtils.getBean(ExampleService.class); // 此處省略... @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 此處省略... } }
點評:這是一種使用最廣泛的一種方式。
第二種:通過JobDataMap參數的方式傳遞ApplicationContext
或Bean。
public class JobDataMapExampleJob implements Job { // 定義KEY public static final String KEY_APP_CTX = "appCtx"; // 此處省略... @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 從JobDataMap中取出ApplicationContext ApplicationContext appCtx = (ApplicationContext) getJobDataMap(context).get(KEY_APP_CTX); // 通過ApplicationContext取各種Bean ExampleService exampleService = appCtx.getBean(ExampleService.class); // 此處省略... } private JobDataMap getJobDataMap(JobExecutionContext context) { return context.getJobDetail().getJobDataMap(); } }
第三種:JobDetail配置為prototype Bean。
定義Job,使用注解注入Bean。
// 定義成Bean @Component("prototypeJobDetailExampleJob") public class PrototypeJobDetailExampleJob implements Job { // 采用注解注入 @Autowired private ExampleService exampleService; @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 此處省略... } }
配置prototype JobDetail Bean。
<bean scope="prototype" id="prototypeJobDetailExampleJob.jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!-- 此處確保名稱不重復 --> <property name="name" value="#{PrototypeJobDetailExampleJob.getNewUuid()}" /> <property name="group" value="groupName" /> <property name="targetObject" ref="prototypeJobDetailExampleJob"/> <property name="targetMethod" value="execute" /> </bean>
立即調度
// 從Spring ApplicationContext中獲取JobDetail。 JobDetail jobDetail = AppCtxUtils.getBean("prototypeJobDetailExampleJob.jobDetail"); // 此處省略代碼 scheduler.addJob(jobDetail, false); String myTrigger = UUID.randomUUID().toString(); Trigger trigger = TriggerBuilder.newTrigger() // .withIdentity(myTrigger, "groupName") // .forJob(jobDetail) // .startNow() // .build(); scheduler.scheduleJob(trigger);
點評:PrototypeJobDetailExampleJob以Spring Bean方式編寫很簡潔,但是配置和使用較復雜。
第四種:Spring提供對Quartz的支持的一種方式。
定義Job
public class SchedulerContextExampleJob implements Job { // 定義KEY public static final String KEY_APP_CTX = "appCtx"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { ApplicationContext appCtx = getApplicationContext(context); // 通過ApplicationContext取各種Bean ExampleService exampleService = appCtx.getBean(ExampleService.class); // 此處代碼省略 } catch (Exception e) { throw new JobExecutionException(e); } } private ApplicationContext getApplicationContext(JobExecutionContext context) throws SchedulerException { // 從SchedulerContext中取出ApplicationContext return (ApplicationContext) context.getScheduler().getContext().get(KEY_APP_CTX); } }
配置JobDetail及Scheduler
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- --> <property name="applicationContextSchedulerContextKey" value="appCtx"/> <!-- 省略其他配置 --> </bean>
以上四種寫法要么寫法冗長,要么配置復雜。對有強迫癥的程序員夠優雅,那么接下來介紹一種更優雅的方式。
public class ExampleJob implements Job { @Autowired private ExampleService exampleService; @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 此處省略... } }
ExampleJob
與第三種PrototypeJobDetailExampleJob
的最大區別:ExampleJob
非Spring Bean,但依然可以使用Spring注解進行Bean的注入。
基本原理:將Quartz實例化的JOB對象實例在使用前讓Spring容器幫忙注入。
廢話不多說直接上代碼。
擴展SpringBeanJobFactory。
public class SpringAutowireCapableJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); // 此處用Spring處理對象 applicationContext.getAutowireCapableBeanFactory().autowireBean(jobInstance); return jobInstance; } }
配置scheduler時指定jobFactory為SpringAutowireCapableJobFactory
。
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobFactory"> <bean class="example.SpringAutowireCapableJobFactory" /> </property> <!-- 省略其他... --> </bean>
感謝各位的閱讀,以上就是“java中怎么實現即時Quartz Job注入Bean”的內容了,經過本文的學習后,相信大家對java中怎么實現即時Quartz Job注入Bean這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。