两者区别与作用:

普通任务:总调度(SchedulerFactoryBean)--> 定时调度器(CronTriggerFactoryBean) --> 调度明细自定义执行方法bean(MethodInvokingJobDetailFactoryBean) -->调度bean(我们定义的job类)

可传参任务:总调度(SchedulerFactoryBean)--> 定时调度器(CronTriggerFactoryBean) -->  调度明细bean(JobDetailFactoryBean)

如上是我们在配置调度器时的具体步骤及相互之间的依赖,区别主要在调度明细bean上,普通任务是(MethodInvokingJobDetailFactoryBean),而可传参任务是(JobDetailFactoryBean):

  1)普通任务可以自定义执行方法,也就是说在其配置的调度bean(我们定义的job类)中我们可以自定义调度器最终执行的方法,可以叫work1也可以叫work2,and so on。而且要记住的一点,必须是无入参的方法!!!(做了一个测试,测试目的是看通过此类型调度类型是否也能传入参数所以定义了一个带入参的自定义方法即public void work(JobExecutionContext jobExecutionContext),最中测试结果是spring quartz会报找不到work方法及No such method work(),其默认执行我们生命的work无入参的方法。

  2)可传参任务必须继承QuartzJobBean,重写protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException方法,其中JobExecutionContext就是我们在定义调度器明细时传入参数的上下文,我们可以通过JobExecutionContext取出传入的map,调度任务最终执行的就是executeInternal方法,使用该调度明细任务无法使用自定义方法。

提供三种形式的定时任务:
1、固定等待时间 @Scheduled(fixedDelay = 时间间隔 )
2、固定间隔时间 @Scheduled(fixedRate = 时间间隔 )
3、Corn表达式 @Scheduled(cron = Corn表达式)

添加依赖(不知道为什么要加jboss-logging依赖,没有会报错)

<!-- 添加springboot对Quartz的支持 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency> <!-- https://mvnrepository.com/artifact/org.jboss.logging/jboss-logging -->
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>

配置quartz.properties

#===============================================================
#Configure Main Scheduler Properties 调度器属性
#===============================================================
#调度器的实例名
org.quartz.scheduler.instanceName = QuartzScheduler
#调度器的实例ID,大多数情况设置为auto即可
org.quartz.scheduler.instanceId = AUTO #===============================================================
#Configure ThreadPool 线程池属性
#===============================================================
#处理Job的线程个数,至少为1,但最多的话最好不要超过100,在多数机器上设置该值超过100的话就会显得相当不实用了,特别是在你的 Job 执行时间较长的情况下
org.quartz.threadPool.threadCount = 5
#线程的优先级,优先级别高的线程比级别低的线程优先得到执行。最小为1,最大为10,默认为5
org.quartz.threadPool.threadPriority = 5
#一个实现了 org.quartz.spi.ThreadPool 接口的类,Quartz 自带的线程池实现类是 org.quartz.smpl.SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool #===============================================================
#Configure JobStore 作业存储设置
#===============================================================
#要使 Job 存储在内存中需通过设置 org.quartz.jobStrore.class 属性为 org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

一、普通任务

1、任务类

package cloud.app.prod.home.quartz.mem;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException; /**
* Author : YongBo Xie </br>
* File Name: ScheduleTask.java </br>
* Created Date: 2018年3月31日 下午3:37:43 </br>
* Modified Date: 2018年3月31日 下午3:37:43 </br>
* Version: 1.0 </br>
*/
@Configuration
@Component // 此注解必加
@EnableScheduling // 此注解必加
public class ScheduleTask { private static Logger logger = Logger.getLogger(ScheduleTask.class); public void marketingActivity() throws FailException {
logger.info("execute activity");
} }

2、Quartz配置类

package cloud.app.prod.home.quartz.mem;

import org.quartz.Trigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean; /**
* Author : YongBo Xie </br>
* File Name: QuartzConfigration.java </br>
* Created Date: 2018年3月31日 下午3:42:04 </br>
* Modified Date: 2018年3月31日 下午3:42:04 </br>
* Version: 1.0 </br>
*/
@Configuration
public class QuartzConfigration { /**
* Details:配置定时任务
*/
@Bean(name = "marketingActivityJobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {// ScheduleTask为需要执行的任务
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否并发执行
* 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
* 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
*/
jobDetail.setConcurrent(false); jobDetail.setName("marketing_activity");// 设置任务的名字
jobDetail.setGroup("marketing_activity");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 /*
* 为需要执行的实体类对应的对象
*/
jobDetail.setTargetObject(task); /*
* marketingActivity为需要执行的方法
* 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的marketingActivity方法
*/
jobDetail.setTargetMethod("marketingActivity");
return jobDetail;
} /**
* Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
*/
@Bean(name = "marketingActivityJobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
tigger.setJobDetail(jobDetail.getObject());
tigger.setCronExpression("0 0 1 * * ?");// 初始时的cron表达式 ,每天1点执行
tigger.setName("marketing_activity");// trigger的name
return tigger; } /**
* Details:定义quartz调度工厂
*/
@Bean(name = "marketingActivityScheduler")
public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
bean.setOverwriteExistingJobs(true);
// 延时启动,应用启动1秒后
bean.setStartupDelay(1);
// 注册触发器
bean.setTriggers(cronJobTrigger);
return bean;
}
}

3、定时查库,并更新任务

package cloud.app.prod.home.quartz.mem;

import javax.annotation.Resource;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.mem.vo.MarketingActivitiesVO;
import cloud.app.prod.home.utils.DSHUtils; /**
* Author : YongBo Xie </br>
* File Name: ScheduleRefreshDatabase.java </br>
* Created Date: 2018年3月31日 下午3:58:08 </br>
* Modified Date: 2018年3月31日 下午3:58:08 </br>
* Version: 1.0 </br>
*/
@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshCron { @Resource(name = "marketingActivityJobDetail")
private JobDetail jobDetail; @Resource(name = "marketingActivityJobTrigger")
private CronTrigger cronTrigger; @Resource(name = "marketingActivityScheduler")
private Scheduler scheduler; @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务
// @Scheduled(cron = "0 0 1 * * ?")
public void scheduleUpdateCronTrigger() throws SchedulerException, FailException {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
String currentCron = trigger.getCronExpression();// 当前Trigger使用的
String searchCron = "0 41 10 ? * *";// 从数据库查询出来的
System.out.println(currentCron);
System.out.println(searchCron); // 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
if (!currentCron.equals(searchCron)) {
MarketingActivitiesVO marketingActivitiesVO = new MarketingActivitiesVO();
marketingActivitiesVO.setId(DSHUtils.generateUUID()); // 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
// 按新的cronExpression表达式重新构建trigger
trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
.withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
currentCron = searchCron;
}
}
}

二、可传参任务

在Spring Boot中使用Quartz时,如果job涉及到调用其他自定义方法,需要通过定义Job Factory实现自动注入

传参关键代码:

1)、接收参数

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
MarketingActivitiesVO marketingActivitiesVO = (MarketingActivitiesVO) dataMap.get("marketingActivitiesVO");
}

2)、传入参数

// 创建一项作业
JobDetail job = JobBuilder.newJob(ScheduleTask.class)
.withIdentity("marketingActivityJob", "marketingActivityGroup")
.build(); // 设置参数
MarketingActivitiesVO marketingActivitiesVO = new MarketingActivitiesVO();
marketingActivitiesVO.setId(DSHUtils.generateUUID());
job.getJobDataMap().put("marketingActivitiesVO", marketingActivitiesVO);

1、自定义MyJobFactory类

package cloud.app.prod.home.quartz;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component; /**
* Author : YongBo Xie </br>
* File Name: MyJobFactory.java </br>
* Created Date: 2018年4月2日 下午3:27:30 </br>
* Modified Date: 2018年4月2日 下午3:27:30 </br>
* Version: 1.0 </br>
*/
@Component
public class MyJobFactory extends AdaptableJobFactory { @Autowired
private AutowireCapableBeanFactory capableBeanFactory; @Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
// 进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}

2、配置SchedulerFactoryBean

package cloud.app.prod.home.quartz;

import java.io.IOException;
import java.util.Properties; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean; import cloud.app.prod.home.quartz.MyJobFactory; /**
* Author : YongBo Xie </br>
* File Name: QuartzConfigration.java </br>
* Created Date: 2018年3月31日 下午3:42:04 </br>
* Modified Date: 2018年3月31日 下午3:42:04 </br>
* Version: 1.0 </br>
*/
@Configuration
@EnableScheduling
public class QuartzConfigration { @Autowired
private MyJobFactory myJobFactory; @Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean(); // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
factory.setOverwriteExistingJobs(true); // 延时启动,应用启动1秒后
// factory.setStartupDelay(1); // 加载quartz数据源配置
// factory.setQuartzProperties(quartzProperties()); // 自定义Job Factory,用于Spring注入
factory.setJobFactory(myJobFactory); return factory;
} /**
* 加载quartz数据源配置
*
* @return
* @throws IOException
*/
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}

3、执行任务类

package cloud.app.prod.home.quartz.mem;

import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.mem.vo.MarketingActivitiesVO;
import cloud.app.prod.home.rabbitmq.mem.MarketingActivitieRabbitMqSender; /**
* Author : YongBo Xie </br>
* File Name: ScheduleTask.java </br>
* Created Date: 2018年3月31日 下午3:37:43 </br>
* Modified Date: 2018年3月31日 下午3:37:43 </br>
* Version: 1.0 </br>
*/
@Configuration
@Component // 此注解必加
@EnableScheduling // 此注解必加
@DisallowConcurrentExecution // 任务同步
public class ScheduleTask extends QuartzJobBean { private static Logger logger = Logger.getLogger(ScheduleTask.class);
@Autowired
private MarketingActivitieRabbitMqSender marketingActivitieRabbitMqSender; @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info("execute activity");
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
MarketingActivitiesVO marketingActivitiesVO = (MarketingActivitiesVO) dataMap.get("marketingActivitiesVO");
logger.info("marketingActivitiesVO.id: " + marketingActivitiesVO.getId());
try {
logger.info("marketingActivitieRabbitMqSender: " + marketingActivitieRabbitMqSender);
marketingActivitieRabbitMqSender.sendRabbitmqDirect(marketingActivitiesVO);
} catch (FailException e) {
e.printStackTrace();
}
} }

4、设置任务类

package cloud.app.prod.home.quartz.mem;

import java.util.Date;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.mem.vo.MarketingActivitiesVO;
import cloud.app.prod.home.utils.DSHUtils; /**
* Author : YongBo Xie </br>
* Project Name: DSH-SCRM </br>
* Created Date: 2018年3月31日 下午3:58:08 </br>
* Modified Date: 2018年3月31日 下午3:58:08 </br>
* Version: 1.0 </br>
*/
@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshCron { private static Logger logger = Logger.getLogger(ScheduleRefreshCron.class); @Autowired
private SchedulerFactoryBean schedulerFactoryBean; @Scheduled(fixedRate = 5000) // 每隔5s查库
// @Scheduled(cron = "0 0 1 * * ?")
public void scheduleUpdateCronTrigger() throws FailException, SchedulerException {
try{
logger.info("----- scheduling job --------"); String searchCron = "*/5 * * * * ?";// 从数据库查询出来的 // 获取一个调度器
// SchedulerFactory factory = new StdSchedulerFactory();
// Scheduler scheduler = factory.getScheduler();
Scheduler scheduler = schedulerFactoryBean.getScheduler(); // 创建一项作业
JobDetail job = JobBuilder.newJob(ScheduleTask.class)
.withIdentity("marketingActivityJob", "marketingActivityGroup")
.build(); // 设置参数
MarketingActivitiesVO marketingActivitiesVO = new MarketingActivitiesVO();
marketingActivitiesVO.setId(DSHUtils.generateUUID());
job.getJobDataMap().put("marketingActivitiesVO", marketingActivitiesVO); // 作业的执行时间(当前时间的下一分钟)
Date runTime = DateBuilder.evenMinuteDate(new Date()); // 创建一个触发器
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger()
.withIdentity("marketingActivityTrigger", "marketingActivityGroup")
.startAt(runTime) //该触发器将在runTime时执行作业
.endAt(new Date(System.currentTimeMillis()+5*1000+60*1000)) //该触发器将在runTime时结束作业
.withSchedule(CronScheduleBuilder.cronSchedule(searchCron)) // 具体执行时间
.build(); // 告诉调度器使用该触发器来安排作业
scheduler.scheduleJob(job, trigger);
// 启动调度器
scheduler.start();
logger.info("------ started scheduler -------"); logger.info("------ waiting 2 minutes ------");
Thread.sleep(2*60*1000); logger.info("------- shutting down ------");
// 关闭调度器
scheduler.shutdown(true);
logger.info("------- shutdown complete -------");
}catch(Exception e){
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
}
}

springboot-quartz普通任务与可传参任务的更多相关文章

  1. spring-quartz普通任务与可传参任务

    两者区别与作用: 普通任务:总调度(SchedulerFactoryBean)--> 定时调度器(CronTriggerFactoryBean) --> 调度明细自定义执行方法bean(M ...

  2. SpringBoot系列: Java应用程序传参和SpringBoot参数文件

    ===========================向java 程序传参的几种形式:===========================1. 使用 OS 环境变量. 这个不推荐. 2. 使用JVM ...

  3. springboot对传参的拦截统一处理

    在学习某网<java秒杀系统方案优化>的课程中,学到了一种springboot对传参的拦截统一处理的方式,特记录一下. 如后台方法一般需要根据token从Session中获取User对象, ...

  4. SpringBoot 2.x (2):请求和传参

    其实请求和传参这些知识属于SpringMVC 不过这也属于必须掌握的知识,巩固基础吧 GET请求: 以第一篇文章自动的方式创建SpringBoot项目: 然后新建Controller: package ...

  5. SpringBoot传参方式

    地址传参 1.创建一个Action类 package com.lion.action; import org.springframework.stereotype.Controller; import ...

  6. SpringBoot 处理 POST Json 传参枚举

    在 Spring 框架中对枚举类型的序列化/反序列化是有限制的. 假设如下面这样在某些情况下就不能正常工作: 123456789 public enum PayChannelEnum implemen ...

  7. Docker 如何动态给SpringBoot项目传参

    关于SpringBoot配置数据源 在项目开发中,我们往往需要配置多套不同的配置环境例如:本地开发.测试环境.部署环境.每一个环境的数据源配置可能都不同,因此需要写不同的数据源配置.如果用Docker ...

  8. springboot实现xml传参和返回值

    1.新建maven工程xml-bean-convert pom.xml如下 <?xml version="1.0" encoding="UTF-8"?&g ...

  9. 二十一、springboot之定制URL匹配规则(项目中遇到的问题:get方式传参,带有小数点,被忽略)

    一.问题描述: get方式传参,在传送价格,积分时(带有小数点),debug后台微服务接受到的参数,却不带小数点,如:price是0.55,后台接受后却是0 二.解决 在WebConfiguratio ...

随机推荐

  1. MyBatis ((一对多和多对一配置)实现持久化操作 之二)

    注: 此文中的实体类还是沿用上一章的Emp和Dept两个类 还是老样子,不细说 直接上代码 01.在emp.xml中  配置和Dept的多对一的相关信息 <?xml version=" ...

  2. Sublime Text2安装emmet

    一.安装Package Control 如果Preferences中没有Package Control,需要手动安装.安装方法如下: 访问Package Controls站点复制一段python命令安 ...

  3. dedecms:解析Robots.txt 协议标准

    Robots.txt 是存放在站点根目录下的一个纯文本文件.虽然它的设置很简单,但是作用却很强大.它可以指定搜索引擎蜘蛛只抓取指定的内容,或者是禁止搜索引擎蜘蛛抓取网站的部分或全部内容. 下面我们就来 ...

  4. 使用 RxJava 的正确姿势

    最近在使用 RxJava 时遇到了一些比较诡异的问题,排查的过程中做了点研究,发现平时大家的用法多多少少都有些问题.有些地方存在隐患,有些用法不够简练,我把这些问题简单做一下分类和总结,供大家参考. ...

  5. [Windows Server 2008] 安装IIS7.5及FTP

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装IISII ...

  6. [系统]no such partition

    电脑系统是win8.1+ubuntu14.2,为了卸载ubuntu,安装CentOS,于是在win8.1下把ubuntu的分区给删除了,重启,出现no such partition grub resc ...

  7. @ResponseBody 返回中文乱码

    第一种解决方法:在@RequestMapping注解添加produces属性 @RequestMapping(value = "testPersonalValidtor.do",p ...

  8. 微信小程序音频长度获取的问题

    小程序推荐使用wx.createInnerAudioContext()创建的innerAudioContext,我们也通过这个接口创建音频.音频的长度可以通过属性获取: 但是,给innerAudioC ...

  9. zabbix实现163邮件报警

    Zabbix 邮件报警 电脑登录网易邮箱配置,把自己的授权码看一下,并写入配置文件 server端安装配置邮件服务器 [root@server ~]# yum -y install mailx dos ...

  10. 【转载】使用IntelliJ IDEA 配置Maven(入门)

    1. 下载Maven 官方地址:http://maven.apache.org/download.cgi 解压并新建一个本地仓库文件夹 2.配置本地仓库路径   3.配置maven环境变量      ...