您的位置:首页 > 编程语言 > Java开发

spring quartz

2016-07-15 15:18 465 查看

spring quartz 任务调度

使用spring + quartz 实现定时任务。

一.所需jar包

<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.spring-context-support</artifactId>
<version>4.2.6.RELEASE_1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>


二.applicationContext.xml 配置

<!-- 添加调度的任务bean 配置对应的class ,即所要执行的任务类(普通的方法类)-->

<bean id="mySchedule" class="com.retosql.thread.RedisToMysqlTask" />

<!- -配置调度具体执行的方法-->
<bean id="myScheduleDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!- -指定类源-->
<property name="targetObject" ref="myPrintSchedule" />
<!- -指定方法-->
<property name="targetMethod" value="startjob" />
<property name="concurrent" value="false" />
</bean>

<!-- 配置调度执行的触发的时间 ,几种情况-->
<!-- 一. 固定时间执行,表达式具体可网上百度-->
<!--
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<
4000
property name="jobDetail" ref="myScheduleDetail" />
<property name="cronExpression">
<value>0 0 8 * * ?</value>
</property>
</bean>
-->
<!-- 二.每2秒调度一次 -->
<!--
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="myScheduleDetail" />
<property name="startDelay" value="0" />
<property name="repeatInterval" value="2000" />
</bean>
-->
<!-- 三.只执行一次-->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="myScheduleDetail" />
<property name="startDelay" value="0" />
<property name="repeatCount">
<value>0</value>
</property>
</bean>

<!-- quartz的调度工厂 调度工厂只能有一个,多个调度任务在list中添加 -->
<!-- 这里的com.retosql.thread.MyDestroySchedulerFactoryBean是重写的类继承
org.springframework.scheduling.quartz.SchedulerFactoryBean-->
<bean id="mySchedulerbean" class="com.retosql.thread.MyDestroySchedulerFactoryBean" lazy-init="false">
<property name="triggers">
<list>
<!--指定配置好的调度任务 -->
<ref bean="simpleTrigger" />
</list>
</property>
</bean>


三.spring配置中加入上述配置,运行tomcat,定时任务就启动了。

四.存在问题

项目部署linux 服务器上时,当tomcat 正常关闭时,定时任务线程没有关闭,原因应该是tomcat关闭时,SchedulerFactory这个主线程关闭了但是调度任务的子线程没关闭。

查看与tomcat有关的进程:ps -ef|grep tomcat

按照网上的解决方式:

1.重写的SchedulerFactoryBean.java

package com.retosql.thread;
import org.quartz.SchedulerException;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

public class MyDestroySchedulerFactoryBean extends SchedulerFactoryBean{

@Override
public void destroy() throws SchedulerException {
// TODO Auto-generated method stub
System.out.println("线程开始销毁");
super.destroy();
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程销毁异常");
throw new RuntimeException(e);
}
}
}


2.在ServletContextListener 的contextDestroyed的方法里让tomcat 延时关闭主线程SchedulerFactory.

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyMainThread implements ServletContextListener{

@Override
public void contextDestroyed(ServletContextEvent arg0) {
ApplicationContext wac = new ClassPathXmlApplicationContext("applicationContext.xml");
Scheduler scheduler = (Scheduler) wac.getBean("mySchedulerbean");
try {
scheduler.shutdown(true);
Thread.sleep(1000);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(InterruptedException e){
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
arg0.getServletContext().log("线程销毁");
}

@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("监听启动");
}

}


3.windows 下两种方式都有效,但是linux 下两种方式都不行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: