Spring 集成quartz框架的两种方式

版权声明:summer https://blog.csdn.net/yk614294861/article/details/84324603

Java项目中常使用的定时器有JDK Timer、Quartz、Spring Task等三种。Quartz的功能强大,配置也比较复杂,适合大型、多定时任务的项目使用。Spring Task配置较为简单轻量,需要Spring框架支持。JDK自带的定时器Timer使用灵活,配置简单,适合中小型项目。这里记录下quartz方式

一、Quartz作业类的继承方式来讲,可以分为两类:

  1. 作业类需要继承自特定的作业类基类,如Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBean;
  2. 作业类即普通的java类,不需要继承自任何基类。

使用QuartzJobBean,需要继承,而且在注入Spring容器中其他service时候需要在schedulerContextAsMap中注入,比较麻烦,否则不能成功(具体操作参考:https://blog.csdn.net/whaosy/article/details/6298686)。

使用MethodInvokeJobDetailFactoryBean则需要指定targetObject(任务实例)和targetMethod(实例中要执行的方法),可以方便注入Spring容器中其他的service。后者优点是无侵入,业务逻辑简单。所以我更推荐的第二种!

二、从任务调度的触发时机来分,这里主要是针对作业使用的触发器,主要有以下两种:

  1. 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
  2. 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean

三、下面针对两种分别讲解

1.作业类继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean

package com.summer.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import com.summer.opendoor.service.OpenDoorService;

//@Component
public class Job extends QuartzJobBean{
	
	public Job() {
		super();
		System.out.println("JOB初始化");
	}

	@Autowired
	private OpenDoorService openDoorService;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		System.out.println("JOB任务执行了");
		//如果没有在schedulerContextAsMap中注入openDoorService ,则这里是null  
		//openDoorService.open();
	}

}

注意图片红框中的引用,分三步,先定义jobDetail,然后定义触发器,最后是调度工厂

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
	
	
	<!--第一步:1.将自定义的job类(已经继承QuartzJobBean) 注入JobDetailFactoryBean  -->
	<bean id="jobDetail"
		class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<property name="jobClass" value="com.summer.job.Job"></property>
		<property name="durability" value="true"></property>
	</bean>

	<!--第二步:2. 定义触发器,并且将jobDetail注入 -->
	<bean id="simpleTrigger"
		class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		<property name="jobDetail" ref="jobDetail" />
		<!-- 调度工厂实例化后,经过3秒开始执行调度 -->
		<property name="startDelay" value="3000" />
		<!-- 每隔2秒执行一次 -->
		<property name="repeatInterval" value="2000" />
	</bean>

	<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
	<!-- 第三步:配置调度工厂  -->
	<bean id="startQuertz" lazy-init="false" autowire="no"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<!-- 管理trigger -->
		<property name="triggers">
			<list>
				<ref bean="simpleTrigger" />
			</list>
		</property>
	</bean>

</beans>

2.作业类不继承特定基类   强烈推荐这种

package com.summer.job;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.summer.opendoor.service.OpenDoorService;

@Component
public class JobMethodInvoke{
	
	public JobMethodInvoke() {
		super();
		System.out.println("JobMethodInvoke初始化");
	}

	@Autowired
	private OpenDoorService openDoorService;

	
	protected void doSomething() {
		System.out.println("JOB任务执行了");
		openDoorService.open();
	}

}

注意中间的引用关系,如下图

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!--第一步 要执行任务的作业类。 -->
	<bean id="testQuartz" class="com.summer.job.JobMethodInvoke" />
	
	<!-- 第二步 将需要执行的定时任务注入JOB中。 -->
	<bean id="jobDetail"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="testQuartz"></property>
		<!-- 任务类中需要执行的方法 -->
		<property name="targetMethod" value="doSomething"></property>
		<!-- 上一次未执行完成的,要等待有再执行。 -->
		<property name="concurrent" value="false"></property>
	</bean>

	<!--第三步 基本的定时器,会绑定具体的任务。 -->	
	<!-- 第一种 SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。配置方式如下: -->
	<!-- <bean id="testTrigger"
		class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		<property name="jobDetail" ref="jobDetail"></property>
		<property name="startDelay" value="3000"></property>
		<property name="repeatInterval" value="2000"></property>
	</bean> -->	
	
	<!-- 第二种 CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。配置方式如下: -->
	<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail" ref="jobDetail" />
		<!-- <!—每天12:00运行一次 —> -->
		<property name="cronExpression" value="0 0 12 * * ?" />
	</bean>	
	
	<!-- 第四步 配置调度工厂 -->
	<bean id="schedulerFactoryBean" lazy-init="true"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<!-- <ref bean="testTrigger"></ref> -->
				<ref bean="cronTrigger" />
			</list>
		</property>
	</bean>
</beans>

猜你喜欢

转载自blog.csdn.net/yk614294861/article/details/84324603