spring quartz

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">
    <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 下两种方式都不行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值