初识Quartz之Job组件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/carson0408/article/details/79844867

        Quartz是一个开源的任务调度框架,它有别于Timer,有比Timer更好的性能。由于故障切换以及负载均衡能力使得Quartz框架具有如下特点:

1.强大的调度功能。

2.灵活的应用方式。

3.分布式和集群能力。

以上三个特点使得Quartz在多任务调度以及分布式中具有很大的作用,以下通过Quart框架中几个重要的组件来了解Quartz框架是如何工作的。关于Quartz框架,我们需要了解的几个组件的概念是:Job组件系列、Trigger组件系列以及Scheduler系列。本文主要讲述的是Job组件系列。


        首先Job是一个接口,如下代码所示,该接口只有一个方法,因此Job实现类只需要实现execute方法即可。

public interface Job {

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 
     * Interface.
     * 
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    /**
     * <p>
     * Called by the <code>{@link Scheduler}</code> when a <code>{@link Trigger}</code>
     * fires that is associated with the <code>Job</code>.
     * </p>
     * 
     * <p>
     * The implementation may wish to set a 
     * {@link JobExecutionContext#setResult(Object) result} object on the 
     * {@link JobExecutionContext} before this method exits.  The result itself
     * is meaningless to Quartz, but may be informative to 
     * <code>{@link JobListener}s</code> or 
     * <code>{@link TriggerListener}s</code> that are watching the job's 
     * execution.
     * </p>
     * 
     * @throws JobExecutionException
     *           if there is an exception while executing the job.
     */
    void execute(JobExecutionContext context)
        throws JobExecutionException;

}

        创建Job实现类之后,需要将Job实例绑定到JobDetail对象中,其中JobDetail中是一个接口,并继承了Serializable和Cloneable接口。

public interface JobDetail extends Serializable, Cloneable 

        创建JobDetail实例需要调用JobBuilder类中的静态方法newJob方法,该方法封装了创建JobBuilder对象的过程。

 public static JobBuilder newJob() {
        return new JobBuilder();
    }
    
    /**
     * Create a JobBuilder with which to define a <code>JobDetail</code>,
     * and set the class name of the <code>Job</code> to be executed.
     * 
     * @return a new JobBuilder
     */
    public static JobBuilder newJob(Class <? extends Job> jobClass) {
        JobBuilder b = new JobBuilder();
        b.ofType(jobClass);
        return b;
    }

        创建JobBuilder对象之后需要绑定Job实现类,通过调用实例方法withIdentity方法来进行绑定的,其中参数group可以缺省。可以看到该方法中通过创建一个JobKey对象,并返回JobBuilder对象,从而实现绑定的。

public JobBuilder withIdentity(String name) {
        key = new JobKey(name, null);
        return this;
    }  
    
    /**
     * Use a <code>JobKey</code> with the given name and group to
     * identify the JobDetail.
     * 
     * <p>If none of the 'withIdentity' methods are set on the JobBuilder,
     * then a random, unique JobKey will be generated.</p>
     * 
     * @param name the name element for the Job's JobKey
     * @param group the group element for the Job's JobKey
     * @return the updated JobBuilder
     * @see JobKey
     * @see JobDetail#getKey()
     */
    public JobBuilder withIdentity(String name, String group) {
        key = new JobKey(name, group);
        return this;
    }
    
    /**
     * Use a <code>JobKey</code> to identify the JobDetail.
     * 
     * <p>If none of the 'withIdentity' methods are set on the JobBuilder,
     * then a random, unique JobKey will be generated.</p>
     * 
     * @param jobKey the Job's JobKey
     * @return the updated JobBuilder
     * @see JobKey
     * @see JobDetail#getKey()
     */
    public JobBuilder withIdentity(JobKey jobKey) {
        this.key = jobKey;
        return this;
    }

        再来看看JobKey的源码,它继承了Key<T>一个泛型类,并且有两个构造函数:

public JobKey(String name) {
        super(name, null);
    }

    public JobKey(String name, String group) {
        super(name, group);
    }

       可以看出这两个构造函数都继承了父类构造函数,接下来看看Key的源码,这也解释了前面withIdentity方法的group参数为何可以缺省,因为它一旦缺省就会默认为DEFAULT_GROUP。

public Key(String name, String group) {
        if(name == null)
            throw new IllegalArgumentException("Name cannot be null.");
        this.name = name;
        if(group != null)
            this.group = group;
        else
            this.group = DEFAULT_GROUP;
    }

        最后回到JobBuilder创建JobDetail对象的最核心的方法build方法:

public JobDetail build() {

        JobDetailImpl job = new JobDetailImpl();
        
        job.setJobClass(jobClass);
        job.setDescription(description);
        if(key == null)
            key = new JobKey(Key.createUniqueName(null), null);
        job.setKey(key); 
        job.setDurability(durability);
        job.setRequestsRecovery(shouldRecover);
        
        
        if(!jobDataMap.isEmpty())
            job.setJobDataMap(jobDataMap);
        
        return job;
    }

        从上面build方法可以看出,内部创建了一个JobDetail实现类对象,并且将一些相关的信息保存到该对象中并返回。从而实现JobDetail的创建。

        从上面整个过程来说,首先实现Job接口创建实现类。然后需要创建JobDetail对象,该对象的创建比较复杂,首先调用JobBuilder类的类方法newJob创建对象,并且调用实例方法withIdentity方法该方法是通过内部创建一个JobKey实例,将Job实现类的实例对象绑定其中,最后调用build方法则是为了创建JobDetail实现类的对象,并为对象初始化一些信息。

        以上就是Job组件系列的关系以及工作流程。


猜你喜欢

转载自blog.csdn.net/carson0408/article/details/79844867
今日推荐