看Spring源码蛮久了,现在使用Spring集成quartz,看能不能用所学的知识,给各位讲清楚spring集成quartz是怎么配置的!看网上好多文章都说,Spring配置quartz挺复杂的。
quarz,石英调度,一个第三方定时调度框架。
Spring的作用是管理Bean,这句话可以概括Spring框架80%的功能。我们使用Spring集成一个第三方框架时,无非就是把需要new的对象,配置到Spring IOC工厂而已。
使用任何一个第三方的框架,都要引入依赖,这个没啥说的。
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.3.2version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>5.0.7.RELEASEversion>
dependency>
public class MyQuartzJob {
public void executeMethod() {
System.out.println("开始执行任务..."+ new Date());
}
}
没错就是这么简单,在类中定义一个方法,这个方法就是你定时要执行的代码。
然后,把这个类交给Spring管理,你用注解或者配置到xml中都可以。我这里配置到xml中
<bean id="myQuartzJob" class="com.kaka.jtest.springboot.biz.scheduler.quartz.MyQuartzJob"/>
扩展:在quartz 1.x的时候自定义的任务类需要继承一个QuartzJobBean的抽象类,然后实现这个类的抽象方法。最后把这个自定义的任务类的全类名设置到JobDetailBean类的jobClass属性中,配置贼麻烦。最头痛的是这个自定义的任务类引用spring中管理的其他bean时(如自己写的userService),不能自动装配,需要通过JobDetailBean类的jobDataMap注入!
都说这一步复杂,是因为没理解quartz的运行原理。我们不扯太多内部实现,顺着大众的逻辑走一下就明白了。
我们上面的那个自定义的任务类,要让quartz帮忙执行的话,需要告诉quartz哪个类的哪个方法要定时执行吧?quartz中有个术语叫任务明细Bean,就是来包装你自定义的任务类的。
<bean id="jobDetailBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myQuartzJob"/>
<property name="targetMethod" value="executeMethod"/>
<property name="concurrent" value="false"/>
bean>
1.x的时候更直白,直接叫JobDetailBean,任务明细Bean嘛~
quartz知道要调用哪个方法后,我们就需要继续告诉quartz什么时候调用了,这个就是触发器,也可以叫做触发策略。因为我们是用户,所以我们想怎么定时就怎么定时~
<bean id="cronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetailBean" />
<property name="cronExpression" value="0,15,30,45 * * * * ?"/>
bean>
上面两个配置好了,现在只差一个启动的入口了。这个入口就是调度工厂,当Spring容器启动时,就会通过这个SchedulerFactoryBean来启动触发器,进而执行我们自定义的定时任务。
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTriggerBean"/>
list>
property>
bean>
可以看到,调度工厂中可以指定多个触发器。也就是3.1和3.2可以写多个,即我们可以自定义多个定时任务,并配置多个触发器。
至此配置已完成!
我是把配置bean的xml,都放到了other/quartz.xml文件中。Spring启动代码如下:
@Test
public void quartzTest() throws InterruptedException {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"other/quartz.xml");
System.out.println(applicationContext);
TimeUnit.SECONDS.sleep(10000L);
}
符合预期~