【第22期】观点:IT 行业加班,到底有没有价值?

Quartz与Spring集成 Job如何自动注入Spring容器托管的对象

转载 2016年05月31日 16:02:48

原文转自:http://www.cnblogs.com/daxin/p/3608320.html?utm_source=tuicool&utm_medium=referral


测试环境 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以后进行属性注入。

举报

相关文章推荐

非spring托管对象如何获取到spring托管对象

非spring托管对象要获取到spring托管对象,主要是对ApplicationContext的获取   总共可以分为以下四种方式获取ApplicationContext: 一,通过sprin...

普通javaBean如何获取到spring托管对象

一些thread类或servlet不能通过spring注解的方式调用spring容器里面的类 尝试将thread或servlet加上@component或@controller注解变成被spring容...

非spring管理的类实例如何托管给spring容器管理

/** * 非spring管理的类实例如何托管给spring容器管理 * * 下面是摘自spring文档 . * pdf版本:spring-framework-reference4.1.3....

Spring -- 手动调用spring托管BEAN

开发过程中,某个未被spring托管的方法想调用一个被spring托管的方法,如果我们像下面代码的方式去调用方法,则会出现空指针的异常。 @Autowired private HfPay...

spring 托管 class 构造器

需要把一个class托管给spring,后期@Autowired 使用, 若在配置中使用 property name="hostInterface" value="${redis.ho...

Struts2 是如何把Action交给Spring托管的?

首先,来看看如何让Spring 来管理Action. 1.在struts.xml中加入   有两种整合方式:      (1) 将Struts的业务逻辑控制器类配置在Spring的配置文...

Struts2 和spring整合的 Action层托管问题

首先分为 entity(实体) dao(数据库操作) service   action四个层 千万不要注解xml混用   通常我么对于四个层的单多例设置为: (1)    action一定要设为多例 ...

为Servlet或普通Java程序注入Spring托管的Bean、数据源

S2SH中都是层层注入,action交给Spring托管。即,往Struts的Action中注入Service,往Service中又注入DAO,这个都是通过配置完成的。 经过对Spring原理和源码...
  • zollty
  • zollty
  • 2013-03-23 20:34
  • 2233

Quartz 框架快速入门(四)--配置文件通过Spring托管

Spring的scheduling.quartz包中对Quartz框架进行了封装,使得开发时不用写任何QuartSpring的代码就可以实现定时任务。Spring通过JobDetailBean,Met...

Spring之通过servlet获取托管的对象

GetSpringBeanServlet的源码: import javax.servlet.ServletException; import javax.servlet.http.Http...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)