在Spring中使用Quartz有两种方式实现:
第一种是任务类继承QuartzJobBean,
第二种则是在配置文件里定义任务类和要执行的方法,类和方法可以是普通类。很显然,第二种方式远比第一种方式来的灵活。

测试环境 Spring3 M2 quartz-2.1.7

我们要达到这样的效果

public class CancelUnpaidOrderTask implements Job {
@Autowired
private AppOrderService orderService; @Override
public void execute(JobExecutionContext ctx) throws JobExecutionException {
...
}

但是Job对象的实例化过程是在Quartz中进行的,AppOrderService是在Spring容器当中的,那么如何将他们关联到一起呢。好在Quartz提供了JobFactory接口,让我们可以自定义实现创建Job的逻辑。

public interface JobFactory {
Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException;
}

那么我们通过实现JobFactory 接口,在实例化Job以后,在通过ApplicationContext 将Job所需要的属性注入即可

在Spring与Quartz集成时 用到的是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类。源码如下,我们只看最关键的地方。

        // Get Scheduler instance from SchedulerFactory.
try {
this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
populateSchedulerContext(); if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
this.jobFactory = new AdaptableJobFactory();
}
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchedulerContextAware) {
((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
}
this.scheduler.setJobFactory(this.jobFactory);
}
}

其中红色标记的是重点,如果我们不指定jobFactory,那么Spring就使用AdaptableJobFactory。我们在来看一下这个类的实现

package org.springframework.scheduling.quartz;

import java.lang.reflect.Method;

import org.quartz.Job;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle; import org.springframework.util.ReflectionUtils; public class AdaptableJobFactory implements JobFactory { public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
return newJob(bundle);
} public Job newJob(TriggerFiredBundle bundle) throws SchedulerException {
try {
Object jobObject = createJobInstance(bundle);
return adaptJob(jobObject);
}
catch (Exception ex) {
throw new SchedulerException("Job instantiation failed", ex);
}
} protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// Reflectively adapting to differences between Quartz 1.x and Quartz 2.0...
Method getJobDetail = bundle.getClass().getMethod("getJobDetail");
Object jobDetail = ReflectionUtils.invokeMethod(getJobDetail, bundle);
Method getJobClass = jobDetail.getClass().getMethod("getJobClass");
Class jobClass = (Class) ReflectionUtils.invokeMethod(getJobClass, jobDetail);
return jobClass.newInstance();
} protected Job adaptJob(Object jobObject) throws Exception {
if (jobObject instanceof Job) {
return (Job) jobObject;
}
else if (jobObject instanceof Runnable) {
return new DelegatingJob((Runnable) jobObject);
}
else {
throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() +
"]: only [org.quartz.Job] and [java.lang.Runnable] supported.");
}
} }

其他的我们都不管,我们就看红色的地方,这里是创建了一个Job,那我们就在这里去给Job的属性进行注入就可以了,让我们写一个类继承它,然后复写这个方法进行对Job的注入。

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;
}
}

接下来把他配置到Spring当中去

<bean id="jobFactory" class="com.gary.operation.jobdemo.demo1.MyJobFactory"></bean>

然后在把org.springframework.scheduling.quartz.SchedulerFactoryBean的jobFactory设置成我们自己的。

<bean name="MyScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <!-- 其他属性省略 -->
  <property name="jobFactory" ref="jobFactory"></property>
</bean>

这样就完成了Spring对Job的注入功能,其实很简单,原理就是在我们扩展JobFactory创建job的方法,在创建完Job以后进行属性注入。

http://www.cnblogs.com/daxin/p/3608320.html

https://github.com/helloworldtang/ch6_2_3/tree/master/src/main/java/com/schedule/quartz

http://my.oschina.net/hhaijun/blog/698498

http://blog.csdn.net/fenglibing/article/details/6847158
http://blog.csdn.net/whaosy/article/details/6298686

Quartz与Spring集成 Job如何自动注入Spring容器托管的对象的更多相关文章

  1. spring mvc:属性无法自动注入

    在使用spring mvc 3开发一个项目模块时,遇到这样一个奇怪的问题: 前端页面发送的请求中,所有参数都无法自动注入到指定的@ModelAttribute对象中,经过检查,参数名称与接受对象的属性 ...

  2. Servlet自动注入Spring容器中的Bean解决方法

    很多情况在进行Web开发的时候需要自己手写Servlet来完成某些功能,而servlet有需要注入Spring容器中的某些bean,这是每次都要手动获取比较麻烦,这里有一个解决方案,只需要写一个ser ...

  3. spring boot测试类自动注入service或dao

    使用Spring Boot进行单元测试时,发现使用@Autowired注解的类无法自动注入,当使用这个类的实例的时候,报出NullPointerException,即空指针异常. Spring Boo ...

  4. Spring框架使用ByName自动注入同名问题剖析

    问题描述   我们在使用spring框架进行项目开发的时候,为了配置Bean的方便经常会使用到Spring当中的Autosire机制,Autowire根据注入规则的不同又可以分为==ByName==和 ...

  5. Spring Boot @Autowired 没法自动注入的问题

    Application 启动类: @SpringBootApplication @EnableConfigurationProperties @ComponentScan(basePackages = ...

  6. 13.SpringMVC和Spring集成(一) && 14.SpringMVC和Spring集成(二)

    1.概念 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,Spring致力于J2EE应用的各层的解决方案,Spring是企业应用开发的“一站式”选择,并贯 ...

  7. web 工程中利用Spring的 ApplicationContextAware接口自动注入bean

    最常用的办法就是用 ClassPathXmlApplicationContext, FileSystemClassPathXmlApplicationContext, FileSystemXmlApp ...

  8. Action中如何通过@Autowired自动注入spring bean ?

    1.讲Action纳入spring的IOC控制 <!-- 采用注解方式自动扫描装配 --> <context:component-scan base-package="co ...

  9. 没有纳入spring管理的类如何注入spring管理的对象

    spring 如何在普通类中调用注入的对象? spring 在Thread中注入@Resource失败,总为null~解决 springmvc 注入总是空指针异常? 以上的几个问题就是我在项目中遇到的 ...

随机推荐

  1. .Net Framework 4.0安装cmd命令

    在安装系统以后和.Net FrameWork 后,通过cmd编译编写的程序时总是提示编译错误.可以通过cmd命令安装相应的.net framework版本. 具体步骤如下: 1.以管理员身份打开cmd ...

  2. [AngularJS] Use ng-model-options to limit $digest

    Refer: http://toddmotto.com/super-fast-angular-ng-model-options-limit-digest-cycles/ Use: <input ...

  3. PHP安全编程:不要让不相关的人看到报错信息(转)

    没有不会犯错的开发者,PHP的错误报告功能可以协助你确认和定位这些错误,可以提供的这些错误的详细描述,但如果被恶意攻击者看到,这就不妙了.不能让大众看到报错信息,这一点很重要.做到这一点很容易,只要关 ...

  4. Maven Build Life Cycle--reference

    What is Build Lifecycle? A Build Lifecycle is a well defined sequence of phases which define the ord ...

  5. TabBarController创建及使用方法简介

    TabBarController创建及使用方法简介 大致讲解一下TabBarController的创建过程: 首先,我们需要一些视图,如创建UIControllerView类型的view1,view2 ...

  6. 第三篇:R语言数据可视化之条形图

    条形图简介 数据可视化中,最常用的图非条形图莫属,它主要用来展示不同分类(横轴)下某个数值型变量(纵轴)的取值.其中有两点要重点注意: 1. 条形图横轴上的数据是离散而非连续的.比如想展示两商品的价格 ...

  7. Java基础知识强化之集合框架笔记13:Collection集合存储学生对象并遍历

    1. Collection集合存储学生对象并遍历: 需求:存储自定义对象并遍历Student(name,age) 分析: (1)创建学生类 (2)创建集合对象 (3)创建学生对象 (4)把学生对象添加 ...

  8. 在Ubuntu上安装使用Systemtap

    因为最近开始学习Nginx,在网上看到别人介绍了一款强大的内核探测工具Systemtap,于是便准备学习下这款探测工具为以后代码分析做准备. 第一步便是安装.在自己电脑上安装的时候,也是费了一番劲儿. ...

  9. python实现登录函数,比较简单

    一个简单的python实现登录以及修改密码的函数 #密码错误3次,锁定登录: password_list = ['] def account_login(): Tries = 3 while Trie ...

  10. HttpClient 发送图片

    var httpClient = new HttpClient(); using (FileStream fs = new FileStream("C:\\1.jpg", File ...