Spring 4 + Quartz(任务调度框架)详解

Java框架

浏览数:72

2020-6-8


简介

    Quartz是一个完全由java编写的开源作业调度框架,它可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。为确保可伸缩性,Quartz采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。这就是Quartz怎样能并发运行多个作业的原理。Quartz依赖一套松耦合的线程池管理部件来管理线程环境。

特点

  1. 可集群
  2. 可伸缩性
  3. 高可用性
  4. 负载均衡

整合示例

1. 使用maven配置示例所需依赖包

    <properties>
        <springframework.version>4.0.6.RELEASE</springframework.version>
        <quartz.version>2.2.1</quartz.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- spring-tx包必须导入,因为Quartz需要依赖该包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- Quartz framework -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>${quartz.version}</version>
        </dependency>
    </dependencies>

2. 配置任务调度执行类,这里有两种方式,第一种方式也是最简单的配置方式

<bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!--指定任务执行的目标Bean-->
		<property name="targetObject" ref="oneBean" />
		<!--指定任务执行类的目标方法-->
		<property name="targetMethod" value="outMessage" />
</bean>

第二种适合处理复杂的业务需求

<bean name="complexJobDetail" 	class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
	<property name="jobClass" value="com.os.china.ScheduledJob" />
	<property name="jobDataMap">
		<map>
			<entry key="towBean" value-ref="towBean" />
		</map>
	</property>
	<property name="durability" value="true" />
</bean>

:jobClass 一个继承自 QuartzJobBean 的自定义类,需要实现 executeInternal 方法。

       jobDataMap 配置所有需要处理的任务类,本示例配置的是 TowBean。

编写自定义 ScheduledJob 类

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class ScheduledJob extends QuartzJobBean{

	private TowBean towBean;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		towBean.outMessage();
	}

	public void setTowBean(TowBean towBean) {
		this.towBean = towBean;
	}
}

3. 任务触发器配置,这里也有两种配置方式,第一种使用 SimpleTriggerFactoryBean 触发器

<bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		<!--配置具体要执行的jobDetail-->
		<property name="jobDetail" ref="simpleJobDetail" />
		<!--初始延迟时间 1s-->
		<property name="startDelay" value="1000" />
		<!--间隔执行时间每2s执行一次-->
		<property name="repeatInterval" value="2000" />
</bean>

第二种使用 CronTriggerFactoryBean 触发器,使用该触发器可以配置出各种复杂的任务执行规则

<!--周日没隔5秒执行一次-->
<bean id="cronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
	<property name="jobDetail" ref="complexJobDetail" />
	<property name="cronExpression" value="0/5 * * ? * SAT-SUN" />
</bean>

4. 配置 SchedulerFactoryBean,来管理和调度任务的执行

<bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobDetails">
			<list>
				<ref bean="simpleJobDetail" />
				<ref bean="complexJobDetail" />
			</list>
		</property>

		<property name="triggers">
			<list>
				<ref bean="simpleTrigger" />
				<ref bean="cronTrigger" />
			</list>
		</property>
</bean>

5. 完整的 quartz-context.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	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">

	<context:component-scan base-package="com.os.china" />

	<!-- 最简单的JobDetail配置 -->
	<bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!--指定任务执行的目标Bean-->
		<property name="targetObject" ref="oneBean" />
		<!--指定任务执行类的目标方法-->
		<property name="targetMethod" value="outMessage" />
	</bean>

	<!-- 除了上面最简单的JobDetail配置外,还可以使用另外一种配置JobDetail的方式,
	该配置方式可处理更加复杂的业务需求 -->
	<bean name="complexJobDetail" 	class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<property name="jobClass" value="com.os.china.ScheduledJob" />
		<property name="jobDataMap">
			<map>
				<entry key="towBean" value-ref="towBean" />
			</map>
		</property>
		<property name="durability" value="true" />
	</bean>

	<bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		<!--配置具体要执行的jobDetail-->
		<property name="jobDetail" ref="simpleJobDetail" />
		<!--初始延迟时间 1s-->
		<property name="startDelay" value="1000" />
		<!--间隔执行时间每2s执行一次-->
		<property name="repeatInterval" value="2000" />
	</bean>

	<!--周日没隔5秒执行一次-->
	<bean id="cronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail" ref="complexJobDetail" />
		<property name="cronExpression" value="0/5 * * ? * SAT-SUN" />
	</bean>
	
	<bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobDetails">
			<list>
				<ref bean="simpleJobDetail" />
				<ref bean="complexJobDetail" />
			</list>
		</property>

		<property name="triggers">
			<list>
				<ref bean="simpleTrigger" />
				<ref bean="cronTrigger" />
			</list>
		</property>
	</bean>

</beans>

6. 创建任务类OneBean

import org.springframework.stereotype.Component;

/**
 * 第一个任务执行Bean
 * @author ZhangPengFei
 * @Discription
 * @Data 2017-2-25
 * @Version 1.0.0
 */
@Component
public class OneBean {
	public void outMessage(){
		System.out.println("hello 我是第一个任务执行类");
	}
}

7. 创建任务类TowBean

import org.springframework.stereotype.Component;

/**
 * 第二个任务执行Bean
 * @author ZhangPengFei
 * @Discription
 * @Data 2017-2-25
 * @Version 1.0.0
 */
@Component
public class TowBean {
	public void outMessage(){
		System.out.println("hello 我是第二个任务执行类");
	}
}

8. 测试

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试类
 * @author ZhangPengFei
 * @Discription
 * @Data 2017-2-25
 * @Version 1.0.0
 */
public class QuartzTest {
	public static void main(String[] args) {
		ApplicationContext app = new ClassPathXmlApplicationContext("quartz-context.xml");
	}
}

9. 执行结果

作者:FEINIK