Quartz任务中调用Spring容器中bean及动态调度任务
Quartz 是开源任务调度框架中的翘首,它提供了强大任务调度机制,同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
Spring为创建Quartz的Scheduler、Trigger和JobDetail提供了便利的FactoryBean类,以便能够在Spring 容器中享受注入的好处。此外Spring还提供了一些便利工具类直接将Spring中的Bean包装成合法的任务。Spring进一步降低了使用Quartz的难度,能以更具Spring风格的方式使用Quartz。概括来说它提供了两方面的支持:
1)为Quartz的重要组件类提供更具Bean风格的扩展类;
2)提供创建Scheduler的BeanFactory类,方便在Spring环境下创建对应的组件对象,并结合Spring容器生命周期进行启动和停止的动作。
第一步: 配置SchedulerFactoryBean
Quartz的SchedulerFactory是标准的工厂类,不太适合在Spring环境下使用。此外,为了保证Scheduler能够感知Spring容器的生命周期,完成自动启动和关闭的操作,必须让Scheduler和Spring容器的生命周期相关联。以便在Spring容器启动后,Scheduler自动开始工作,而在Spring容器关闭前,自动关闭Scheduler。为此,Spring提供SchedulerFactoryBean,这个FactoryBean大致拥有以下的功能:
1)以更具Bean风格的方式为Scheduler提供配置信息;
2)让Scheduler和Spring容器的生命周期建立关联,相生相息;
3)通过属性配置部分或全部代替Quartz自身的配置文件。
spring容器中的bean只能放到SchedulerContext里面传入job中。
<bean name="scheduler" > <!-- 注入数据源 --> <property name="dataSource"> <ref bean="dataSource" /> </property><property name="transactionManager" ref="txManager"></property> <!-- 延迟30秒启动Scheduler --> <property name="startupDelay" value="30"></property><property name="schedulerContextAsMap"> <map> <!-- spring 管理的service需要放到这里,才能够注入成功 --> <description>schedulerContextAsMap</description> <entry key="jobService" value-ref="jobService"/></map> </property> <!-- 通过applicationContextSchedulerContextKey属性配置spring上下文 --> <property name="applicationContextSchedulerContextKey"> <value>applicationContext</value> </property> </bean>
JobDetail jobDetail = new JobDetail("jobName", "jobGroup",TestJob.class);jobDetail.setDescription("Description");CronTrigger trigger = new CronTrigger("TriggerName","TriggerGroup", "CronContent");try { if (!scheduler.isStarted()) {scheduler.start();}scheduler.scheduleJob(jobDetail, trigger); catch (SchedulerException e) { }
public class TestJob extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {Scheduler scheduler = (Scheduler) context.getScheduler(); String jobName = context.getJobDetail().getName();String jobGroup = context.getJobDetail().getGroup();//获取JobExecutionContext中的service对象 try { //获取JobExecutionContext中的service对象 SchedulerContext schCtx = context.getScheduler().getContext(); //获取Spring中的上下文 ApplicationContext appCtx = (ApplicationContext)schCtx.get("applicationContext");jobService= (JobService)appCtx.getBean("jobService");....} catch (SchedulerException e1) {// TODO 尚未处理异常e1.printStackTrace();} } };