Spring是个用处十分广泛的容器,而Quartz则是一个具有灵活性的框架,适用于各大框架的整合。本文主要讲述Spring整合Quartz的流程。
前面的博文已经详细讲解了Quartz的知识点,今天主要讲的是整合相关的知识。首先,Quartz配置作业有两种方式。一种是MethodInvokingJobDetailFactoryBean,另一种是JobDetailFactoryBean。前者对应的的任务类是一个普通的类,而后者则需要继承QuartzJobBean。
1.两种配置作业的方式的作业类
1.MethodInvokingJobDetailFactoryBean方式对应的Job类
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Component;
@Component("simpleBean")
public class SimpleBean {
public void doWork() {
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=new Date();
System.out.println("我是比较简单的工作,所以每隔两秒触发一次,当前时间为:"+simpleDateFormat.format(date));
}
}
2.JobDetailFactoryBean方式对应的Job类
首先定义一个简单的工作类。
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Component;
@Component("complexBean")
public class ComplexBean {
public void doMyWork()
{
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=new Date();
System.out.println("我是比较复杂的工作,所以每5秒触发一次:"+simpleDateFormat.format(date));
}
}
再创建一个实现QuartzJobBean的类,并将以上简单类注入其中。
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MyScheduleJob extends QuartzJobBean {
private ComplexBean complexBean;
public void setComplexBean(ComplexBean complexBean) {
this.complexBean = complexBean;
}
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
// TODO Auto-generated method stub
this.complexBean.doMyWork();
}
}
2.第一种方法的JobDetail和Trigger的配置
前面已经完成两种Job的编写,接下来就是进行配置,这也是Spring整合的优势,避免了硬编码耦合的问题,通过Spring容器的IOC特性,为JobDetail绑定Job对象,这里的JobDetail使用的是MethodInvokingJobDetailFactoryBean。然后配置Trigger,同样的利用IOC注入Trigger需要的JobDetail对象。并为Trigger调度设置参数,然后具体代码如下:
<!-- 以下是任务调度的配置-两种配置作业的方式 -->
<!-- 第一种配置作业的方式:MethodInvokingJobDetailFactoryBean -->
<!-- 首先配置JobDetail,需要将代表Job的Bean绑定到JobDetail中-->
<bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="simpleBean"/>
<property name="targetMethod" value="doWork"/>
</bean>
<!-- 配置Trigger,将jobDetail配置到其中 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="simpleJobDetail"/>
<property name="startDelay" value="1000"/>
<property name="repeatInterval" value="2000"/>
</bean>
3.第二种方法的JobDetail和Trigger的配置
前面讲了MethodInvokingJobDetailFactoryBean方法的配置,现在讲解的是JobDetailFactoryBean来创建JobDetail对象,这里的配置稍有不同,MethodInvokingJobDetailFactoryBean只需要配置targetObject和targetMethod属性,而该方法有所不同。另外本方法使用的Trigger是CronTrigger。具体配置如下:
<!-- 第二种配置作业的方式:JobDetailFactoryBean -->
<!-- 配置第二种JobDetail,并将复杂Bean进行绑定 -->
<bean id="complexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.carson.myspringquartz.jobbean.MyScheduleJob"/>
<property name="jobDataMap" >
<map>
<entry key="complexBean" value-ref="complexBean"/>
</map>
</property>
<property name="durability" value="true"/>
</bean>
<!-- 配置对应的Trigger,这里使用CronTrigger -->
<bean id="complexTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="complexJobDetail"/>
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
4.利用Shceduler将JobDetail和Trigger进行统一管理
<!-- 配置相应的Scheduler,将所有的JobDetail和Trigger统一管理 -->
<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="complexTrigger"/>
</list>
</property>
</bean>
只需要指定jobDetails和triggers两个属性的值即可,各自的值需要用<list></list>进行罗列。
5.完整的配置文件
web.xml:主要配置SpringMVC的上下文
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 设置dispatchservlet的匹配模式,通过把dispatchservlet映射到/,默认servlet会处理所有的请求,包括静态资源 -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
springmvc.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"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
default-lazy-init="true">
<!-- 通过mvc:resources设置静态资源,这样servlet就会处理这些静态资源,而不通过控制器 -->
<!-- 设置不过滤内容,比如:css,jquery,img 等资源文件 -->
<mvc:resources location="/*.html" mapping="/**.html" />
<mvc:resources location="/css/*" mapping="/css/**" />
<mvc:resources location="/js/*" mapping="/js/**" />
<mvc:resources location="/images/*" mapping="/images/**" />
<!-- 设定消息转换的编码为utf-8防止controller返回中文乱码 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<!-- 添加注释驱动 -->
<mvc:annotation-driven/>
<!-- 默认扫描的包路径 -->
<context:component-scan base-package="com.carson.myspringquartz.jobbean" />
<!-- mvc:view-controller可以在不需要Controller处理request的情况,转向到设置的View -->
<!-- 像下面这样设置,如果请求为/,则不通过controller,而直接解析为/index.jsp -->
<mvc:view-controller path="/" view-name="index" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<!-- 配置jsp路径前缀 -->
<property name="prefix" value="/WEB-INF/jsps/"></property>
<!-- 配置URl后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 以下是任务调度的配置-两种配置作业的方式 -->
<!-- 第一种配置作业的方式:MethodInvokingJobDetailFactoryBean -->
<!-- 首先配置JobDetail,需要将代表Job的Bean绑定到JobDetail中-->
<bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="simpleBean"/>
<property name="targetMethod" value="doWork"/>
</bean>
<!-- 配置Trigger,将jobDetail配置到其中 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="simpleJobDetail"/>
<property name="startDelay" value="1000"/>
<property name="repeatInterval" value="2000"/>
</bean>
<!-- 第二种配置作业的方式:JobDetailFactoryBean -->
<!-- 配置第二种JobDetail,并将复杂Bean进行绑定 -->
<bean id="complexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.carson.myspringquartz.jobbean.MyScheduleJob"/>
<property name="jobDataMap" >
<map>
<entry key="complexBean" value-ref="complexBean"/>
</map>
</property>
<property name="durability" value="true"/>
</bean>
<!-- 配置对应的Trigger,这里使用CronTrigger -->
<bean id="complexTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="complexJobDetail"/>
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<!-- 配置相应的Scheduler,将所有的JobDetail和Trigger统一管理 -->
<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="complexTrigger"/>
</list>
</property>
</bean>
</beans>