文档章节

Spring Quartz 任务静态配置和动态添加

满小茂
 满小茂
发布于 2016/12/20 17:28
字数 937
阅读 450
收藏 4

Quartz任务可以静态配置到配置文件中,也可以动态添加.

1.Quartz任务 静态配置

其中 <property name="concurrent" value="false"/>,是设置job不能并发执行。

    <!-- 删除旧数据定时任务 -->
    <!-- 删除新闻数据job -->
    <bean id="delOldNewsJobDetail"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="deleteOldNewsJob"/>
        <property name="targetMethod" value="doJob"/>
        <property name="concurrent" value="false"/>   <!--防止job并发执行-->
    </bean> 
    <!-- tigger -->
    <bean id="deleteOldNewsJobTrigger"
          class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- org.springframework.scheduling.quartz.CronTriggerBean -->
        <property name="jobDetail">
            <ref bean="delOldNewsJobDetail"/>
        </property>
        <property name="cronExpression">
            <!-- cron表达式  -->
            <value>${delete.old.news.cron}</value> 
        </property>
    </bean>

 

定时任务执行类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


@Component
public class DeleteOldNewsJob {
  
  private Logger logger = LoggerFactory.getLogger(DeleteOldNewsJob.class);
  
  @Value("${delete.old.news.job.enable}")
  private boolean enabled;
  
  @Autowired
  private NewsFeedMapper newsFeedMapper;

  public void doJob() {
    if (!enabled) {
      logger.info("delete old news job enabled = false");
      return;
    }
    logger.info("----------------delete old news begins------------------");
    newsFeedMapper.deleteOldNews();
    logger.info("----------------delete old news end---------------------");
  }
}

 

2.Quartz任务 动态添加

 定时器动态添加任务类

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Service;

/**
 * Quartz定时任务调度器管理类
 *
 */
@Component
public class QuartzManager{
  /**
   * 任务组名
   */
  private static final String JOB_GROUP_NAME = "PUSH_MESSAGE_JOB_GROUP";
  /**
   * 触发器组名
   */
  private static final String TRIGGER_GROUP_NAME = "PUSH_MESSAGE_TRIGGER_GROUP";
  /**
   * Quartz调度器
   */
  private Scheduler scheduler;

  /**
   * 初始化调度器
   *
   * @throws SchedulerException
   */
  @PostConstruct
  public void init() throws SchedulerException {
    SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    scheduler = schedulerFactory.getScheduler();
  }

  /**
   * 添加一个定时任务,使用默认的任务组名、触发器组名,触发器的名称跟任务的一样
   *
   * @param jobName 任务名称
   * @param cls 任务
   * @param time 任务执行的时间,Cron表达式
   */
  @SuppressWarnings("rawtypes")
  @Override
  public void addJob(String jobName, Class cls, String time) {
    try {
      JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);
      CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);
      trigger.setCronExpression(time);
      scheduler.scheduleJob(jobDetail, trigger);
      if (!scheduler.isShutdown()) {
        scheduler.start();
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 移除一个定时任务 使用默认的任务组名、触发器组名,触发器名跟任务名一致
   *
   * @param jobName 任务名称
   */
  @Override
  public void removeJob(String jobName) {
    try {
      scheduler.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 暂停触发器
      scheduler.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
      scheduler.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
    } catch (SchedulerException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 启动所有定时任务
   */
  @Override
  public void startJobs() {
    try {
      scheduler.start();
    } catch (SchedulerException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 关闭所有定时任务
   */
  @Override
  public void shutdownJobs() {
    try {
      if (!scheduler.isShutdown()) {
        scheduler.shutdown();
      }
    } catch (SchedulerException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 当关闭应用时,停止所有调度任务,并关掉调度器
   */
  @PreDestroy
  public void stopQuartz() {
    try {
      if (!scheduler.isShutdown()) {
        scheduler.shutdown();
      }
    } catch (SchedulerException e) {
      throw new RuntimeException(e);
    }
  }
}

 

测试动态定时任务添加

任务类

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class TestJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("time out!!!");
    }
}

 

测试类,需要使用

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class QuartzTest {
    @Resource
    private QuartzManager manager;
    @Test
    public void test(){
        manager.startJobs();
        manager.addJob("test", TestJob.class,"*/5 * * * * ?");
        while (true);
    }
}

 

Quartz防止job并发执行

Quartz框架中防止任务并行可以有两种方案:

1、如果是通过MethodInvokingJobDetailFactoryBean在运行中动态生成的Job,配置的xml文件有个concurrent属性,这个属性的功能是配置此job是否可以并行运行,如果为false则表示不可以并行运行,否则可以并行。如果一个job的业务处理发费的时间超过了job的启动的间隔时间(repeatInterval),这个属性非常有用。如果为false,那么,在这种情况下,当前job还在运行,那么下一个job只能延时运行。如果为true,那么job就会并行运行。

2、如果是通过自定义要执行的任务的类的名称实现job的话,则有另一种方式:

默认的任务的类实现org.quartz.Job接口,此时任务是stateless(无状态的),即会出现并行的情况,那么如何避免这种情况发生呢?

解决方案:使QuartzJobBean类实现org.quartz.StatefulJob接口即可(StatefulJob接口仅仅是扩展了 Job 接口,未加入新的方法,可以不需实现Job接口了),那么此时任务就会变成stateful(有状态的),此时的任务也就会串行执行了。

 

© 著作权归作者所有

下一篇: CPU缓存行
满小茂
粉丝 79
博文 122
码字总数 138345
作品 0
成都
程序员
私信 提问
Quartz任务监控管理 (1)

Quartz任务监控管理,类似Windows任务管理器,可以获得运行时的实时监控,查看任务运行状态,动态增加任务,暂停、恢复、移除任务等。对于动态增加任务,可以参加我的前一篇文章《Quartz如何...

光石头
2011/06/12
1K
1
实现Spring中的任务调度及异步执行

首先要端正一下本人的态度,开发了很长时间的Java Web项目,寄托于Spring MVC的架构,多数时间都是在处理业务逻辑问题,所以我个人单纯地认为Web开发,多线程的应用场景应该不多,能不用尽量...

chace0120
2014/08/01
1K
1
liuht777/uncode-scheduler

uncode-schedule 基于Spring Task + Zookeeper的分布式任务调度组件,非常小巧,使用简单,只需要引入jar包。不需要单独部署服务端。确保所有任务在集群中不重复,不遗漏的执行。支持动态添加...

liuht777
2017/10/26
0
0
项目ITP(六) spring4.0 整合 Quartz 实现动态任务调度

2014-05-18 12:51 by Jeff Li 前言   系列文章:[传送门]   项目需求:      http://www.cnblogs.com/Alandre/p/3733249.html      上一博客写的是基本调度,后来这只能用于,...

泥沙砖瓦浆木匠
2014/05/18
9.1K
0
Quartz的简单易懂定时任务实现

作为一个优秀的开源调度框架,Quartz 具有以下特点: 强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求; 灵活的应用方式,例如支持任务和调度的多种组合方式,支持...

begrateful
2018/09/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

最简单的获取相机拍照的图片

  import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import andr......

MrLins
今天
6
0
说好不哭!数据可视化深度干货,前端开发下一个涨薪点在这里~

随着互联网在各行各业的影响不断深入,数据规模越来越大,各企业也越来越重视数据的价值。作为一家专业的数据智能公司,个推从消息推送服务起家,经过多年的持续耕耘,积累沉淀了海量数据,在...

个推
今天
9
0
第三方支付-返回与回调注意事项

不管是支付宝,微信,还是其它第三方支付,第四方支付,支付机构服务商只要涉及到钱的交易都要进行如下校验,全部成功了才视为成功订单 1.http请求是否成功 2.校验商户号 3.校验订单号及状态...

Shingfi
今天
5
0
简述Java内存分配和回收策略以及Minor GC 和 Major GC(Full GC)

内存分配: 1. 栈区:栈可分为Java虚拟机和本地方法栈 2. 堆区:堆被所有线程共享,在虚拟机启动时创建,是唯一的目的是存放对象实例,是gc的主要区域。通常可分为两个区块年轻代和年老代。更...

DustinChan
今天
7
0
Excel插入批注:可在批注插入文字、形状、图片

1.批注一直显示:审阅选项卡-------->勾选显示批注选项: 2.插入批注快捷键:Shift+F2 组合键 3.在批注中插入图片:鼠标右键点击批注框的小圆点【重点不可以在批注文本框内点击】----->调出批...

东方墨天
今天
7
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部