这篇文章主要讲解了“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这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/geektao/blog/3142970