xxjob怎么启动_spring+quartz两种整合方式:代码创建job+xml配置创建job

quartz交流QQ群:77383408,喜欢的同行一起来探讨问题吧

最近在项目中需要用到quartz,开始使用的xml配置创建的job,一切ok。后来觉得每次添加任务都要写一大段xml,就将job放入了数据库,在spring启动时去启动数据库中保存的所有job。

其中遇到问题,无法注入spring管理的bean。本文是解决方案,研究了几天,终于找到原因了!

首先,本文实现使用的是内存型,没有持久化到数据库。

一、quartz.properties文件

#调度器名,无关紧要,名字任意定

org.quartz.scheduler.instanceName = XXScheduler

org.quartz.scheduler.instanceId = AUTO

#============================================================================

# Configure ThreadPool   配置数据库连接池

#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount = 12

org.quartz.threadPool.threadPriority = 5

#============================================================================

# Configure JobStore  配置做业存储方式

#============================================================================

#相当于扫描频率,如果系统基于秒级,应培植成1000,quartz默认为分级(60000)

org.quartz.jobStore.misfireThreshold = 1000

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

二、创建任务Job

方法一:使用xml方式配置job

0/1 * * * * ?

好了,至此使用xml方式配置job就全部完毕了。

其中值得注意的是下面两句代码:自定义MyJobFactory,在job类里面才可以注入spring的service。

public class MyJobFactory extends AdaptableJobFactory {

// 这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.

@Autowired

private AutowireCapableBeanFactory capableBeanFactory;

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

// 调用父类的方法

Object jobInstance = super.createJobInstance(bundle);

// 进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.

capableBeanFactory.autowireBean(jobInstance);

return jobInstance;

}

}

/**

* Job任务类,实现Job接口,可以成功注入service

*/

public class JobClassTest implements Job {

@Autowired

private ProductBaseDao productBaseDao;

@Override

public void execute(JobExecutionContext context) throws JobExecutionException {

ProductBase p = productBaseDao.load(ProductBase.class, 2);

System.out.println("注入service成功!查询结果为:"+p);

}

}

至此,启动容器,job成功启动。

方式二:使用代码创建Job

表结构:本示例只需要一张表即可!

数据库有了记录,那么我们就需要在spring容器启动后,将所有记录获取出来,并通过代码创建每一个job。

在applicationContext.xml配置文件最末加上这一句,即可在spring启动后,去执行指定类中的方法。

/**

* 在Spring容器将所有的Bean都初始化完成之后的操作

*/

public class InstantiationTracingBeanPostProcessor implements ApplicationListener {

@Autowired

private TimerJobService timerJobService;

@Autowired

private MyJobFactory myJobFactory;

@Override

public void onApplicationEvent(ContextRefreshedEvent event) {

// 避免onApplicationEvent方法被执行两次

if(event.getApplicationContext().getParent() == null){

try {

// 获取Scheduler对象,并自定义jobFactory

Scheduler scheduler = QuartzUtil.getInstance();

scheduler.setJobFactory(myJobFactory);

// 查询所有正常状态的定时任务,并在容器启动后,启动任务

List jobs = timerJobService.getNormalList();

for(TimerJob record : jobs){

Integer id = record.getId();

String name = record.getJobName()+"_"+id;

String group = record.getJobGroup()+"_"+id;

// 加载job类

Class extends Job> clazz = null;

try {

clazz = (Class extends Job>) Class.forName(record.getClassName());

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//生成jobDetail

JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(name, group).build();

//表达式调度构建器

CronScheduleBuilder cornSB= CronScheduleBuilder.cronSchedule(record.getCronExpression());

//生成触发器

CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cornSB).build();

//添加job

scheduler.scheduleJob(jobDetail, trigger);

}

//开始执行shceduler

scheduler.start();

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

其中创建Scheduler实例方法为:

public class QuartzUtil {

private static SchedulerFactory ssf = new StdSchedulerFactory();

/**

* 获取Scheduler实例,使用工厂模式获取

* @return

*/

public static Scheduler getInstance(){

Scheduler sched = null;

try {

sched = ssf.getScheduler();

} catch (SchedulerException e) {

e.printStackTrace();

}

return sched;

}

}

其中关键代码为:scheduler.setJobFactory(myJobFactory) ;同xml配置一样,需要指定自定义的JobFactory。

最开始,我是这样设置的:scheduler.setJobFactory(new MyJobFactory());

可是这样的结果就是,任务全部启动了,可是在job任务类注入不了bean。思考了很久,才突然发现, MyJobFactory是使用new关键字实例化出来的,在spring中,自己new出来的都不会交给spring的context去管理!!!

既然找到问题所在,解决就简单多了,只需要将MyJobFactory交给spring中去,再在上文通过注解注入即可!

在MyJobFactory.java类最上面添加@component注解,启动时spring去扫描组件会将该类注入。

@Component

public class MyJobFactory extends AdaptableJobFactory {......}

至此,问题全部解决,两种创建job的方法,个人觉得第二种比较简单。需要新增任务时,只需要在数据库添加一条记录,再添加一个对应的job类即可。

有了这一张表,同样可以配置后台页面,实现对任务的控制,这里就不讲啦!

最后,欢迎喜欢quartz的人,加入QQ群:77383408

把你的问题说出来集思广益,避免大家重蹈覆辙。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文版目录总汇及内容提要 第一章. 企业应用中的作业调度 内容提要:什么是作业调度,作业调度为什么说是重要的,企业应用中的作业调度,非企业应用中的作业调度,作业调度与工作流,关于作业调度其他可选择方案 第二章. Quartz 起步 内容提要:本章对 Quartz 框架一个快速的入门介绍,同时也大略指导你从哪里下载,构建和安装这个框架 第三章. Hello Quartz (第一部分) 内容提要:建立 Hello Quartz 工程,并创建一个 Quartz Job 类 ScanDirectoryJob. 第三章. Hello Quartz (第二部分) 内容提要:创建一个 Quartz Scheduler,关联上一个 Quartz Trigger 以编程方式调度前面编写的 ScanDirectoryJob 运行。 第三章. Hello Quartz (第三部分) 内容提要:通过配置 quartz.properties、quartz_jobs.xml 以声明的方式调度 ScanDirectoryJob 运行。 第三章. Hello Quartz (第四部分) 内容提要:让我们最后简单讨论打包一个用到了 Quarts 框架的应用程序的流程,需要依赖于哪些包,也以此来结束本章的内容。 第四章. 部署 Job (第一部分) 内容提要:介绍 Scheduler 和 SchedulerFactory 有哪些类型、SchedulerFactory 的关键 API 方法;以及如何通过 java.util.Properties 实例或默认 quartz.properties 文件创建 Scheduler。 第四章. 部署 Job (第二部分) 内容提要:如何管理 Scheduler(启动、停止、Standby 模式)。还介绍了 JobJobExecutionContext、JobDetail、JobDataMap,及如何访问 JobDataMap 中的数据。有状态和无状态的 Job。 第四章. 部署 Job (第三部分) 内容提要:Job 的易失性、持久性和可恢复性,如何从 Scheduler 中移除、中断 JobQuartz 已为我们提供了哪些 Job。最后是 Java 线程的简单介绍。 第四章. 部署 Job (第四部分) 内容提要:线程在 Quartz 中的用法,主处理线程:QuartzSchedulerThread 和 Quartz 工作者线程。Quartz Trigger 和 Calendar 各有哪些类型和如何使用。 第五章. Cron 触发器及相关内容 (第一部分) 内容提要:引入 Quartz CronTrigger 及简单使用 CronTrigger 来部署一个 Job 第五章. Cron 触发器及相关内容 (第二部分) 内容提要:详细介绍了 cron 表达式的格式和像 , - * ? / L W C # 特殊符号的使用 第五章. Cron 触发器及相关内容 (第三部分) 内容提要:CronTrigger 使用起(startTime) 迄(endTime) 日期的使用。TriggerUtils 简单方便的创建 Trigger。应用 JobInitializationPlugin 在 quartz_jobs.xml 配置文件中写 Cron 表达式。 第五章. Cron 触发器及相关内容 (第四部分) 内容提要:Cron 表达式 Cookbook,列举了各种 Cron 表达式的写法和意义,有助于更好的理解 Cron 表达式;还用了 TriggerUtils 创建了一个即刻触发的 Trigger。 第六章. Job 存储和持久化 (第一部分) 内容提要:介绍 Quartz 中的 Job 存储,JobStore 接口相关 API 方法。使用 RAMJobStore 来实现 Job 存储及它的优缺点。 第六章. Job 存储和持久化 (第二部分) 内容提要:使用持久性的 JobStore,可用类型 JobStoreTX 和 JobStoreCMT。持久性 JobStore 是通过数据库来完成的,哪可支持哪些数据及需要创建些什么表。 第六章. Job 存储和持久化 (第三部分) 内容提要:使用和配置 JobStoreTX,需要为不同数据库平台指定不同的驱动代理( DriverDelegate),和 quartz.properties 中与 JobStoreTX 相关配置说明。 第六章. Job 存储和持久化 (第四部分) 内容提要:为 JobStoreTX 通过在 quartz.properties 配置创建数据源,并在 Scheduler 中使用数据源 第六章. Job 存储和持久化 (第五部分

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值