这篇文章主要讲解了“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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。