quartz源码阅读(一),先开坑

首先,我使用的quartz的版本

<dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.3.0</version>
</dependency>

首先,main函数

  public static void main(String[] args) throws SchedulerException {
        //1.创建schedulerFactory的工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //2.从工厂中获取调度器实例
        Scheduler scheduler = schedulerFactory.getScheduler();

        //创建JobDetail
        JobDetail jobDetail = JobBuilder.newJob(RAMJob.class)
                .withDescription("this is a ram job")
                .withIdentity("ramjob","ramGroup")
                .build();
        //任务运行的时间,simpleSchedle类型触发器有效
        long time = System.currentTimeMillis() + 3 * 1000L;
        Date startTime = new Date(time);
        //创建Trigger
            //使用SimpleScheduleBuilder或者CronSchedulerBuilder
        Trigger trigger = TriggerBuilder.newTrigger()
                .withDescription("触发器")
                .withIdentity("ramTrigger","ramTriggerGroup")
                .startAt(startTime)
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        //注册任务和定时器
        scheduler.scheduleJob(jobDetail,trigger);

        //启动调度器
        scheduler.start();
        log.info("启动时间:"+sdf.format(new Date()));

    }
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
创建作业调度的工厂类:
首先看StdSchedulerFactory
constants:变量
太多了,等会用到再来看
constructors:构造方法
/**
生成一个没有未初始化的StdSchedulerFactory
*/
public StdSchedulerFactory()
/**
下面这两个,其实是一个直接的Properties类型的,另一个是这个properties的fileName,
其实就是通过InputStream解析这个文件将封装一个出properties,最后还是通过 initialize(props);
给变量:private PropertiesParser cfg;赋值
this.cfg = new PropertiesParser(props);

*/

public StdSchedulerFactory(Properties props) throws SchedulerException {
        initialize(props);
}
public StdSchedulerFactory(String fileName) throws SchedulerException {
        initialize(fileName);
    }

//2.从工厂中获取调度器实例

        Scheduler scheduler = schedulerFactory.getScheduler();
  public Scheduler getScheduler() throws SchedulerException {
        if (cfg == null) {
            initialize();//此次会去解析是否有quartz.proterties文件,如果有则用你的,如果没有,那就会用他jar包中的
            在org/quartz/quartz.properties
            /**
            By default a properties file named "quartz.properties" is loaded from
     * the 'current working directory'. If that fails, then the
     * "quartz.properties" file located (as a resource) in the org/quartz
     * package is loaded. If you wish to use a file other than these defaults,
     * you must define the system property 'org.quartz.properties' to point to
     * the file you want.
     */
     //quartz.properties中大致涉及:线程池中的线程数,线程优先级,具体可以看
    // https://www.jianshu.com/p/14f86c6efe22
        }

        SchedulerRepository schedRep = SchedulerRepository.getInstance();

        Scheduler sched = schedRep.lookup(getSchedulerName());

        if (sched != null) {
            if (sched.isShutdown()) {
                schedRep.remove(getSchedulerName());
            } else {
                return sched;
            }
        }

        sched = instantiate();

        return sched;
    }
    //会生成一个Scheduler接口实现的的StdScheduler
    在StdScheduler中有个变量:
    private QuartzScheduler sched;
    This is the heart of Quartz, an indirect implementation of the <code>{@link org.quartz.Scheduler}</code>
    quartz的中心,间接的实现了Scheduler接口
    StdScheduler里面的调用方法,都是使用QuartzScheduler里面的方法

    划重点QuartzScheduler这个类,有点复杂,后面再讲

    下面看JobDetail
    关于Jobdetail和Trigger的介绍
    /**
Quartz does not store an actual instance of a <code>Job</code> class, but
 * instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
 quartz中不保存一个真实的job类,但是可以通过jobdetail来定义一个实例
 * <code>Job</code>s have a name and group associated with them, which
 * should uniquely identify them within a single <code>{@link Scheduler}</code>.
 job需要一个name和group来关联他们,

  <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
 * are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
 * but a single <code>Trigger</code> can only point to one <code>Job</code>.
触发器是jobs的调度的机制。一个job可以对应多个Trigger,但是trigger只可以对应一个job
    */

//创建JobDetail

 JobDetail jobDetail = JobBuilder.newJob(RAMJob.class)
                .withDescription("this is a ram job")
                .withIdentity("ramjob","ramGroup")
                .build();
 使用构造器模式:
 	新建一个JobDetailImpl

//创建Trigger

     //使用SimpleScheduleBuilder或者CronSchedulerBuilder
        Trigger trigger = TriggerBuilder.newTrigger()
                .withDescription("触发器")
                .withIdentity("ramTrigger","ramTriggerGroup")
                .startAt(startTime)
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
其中在TriggerBuilder中的withSchedule()方法
/**
     * Set the {@link ScheduleBuilder} that will be used to define the 
     * Trigger's schedule.
     * 
     * <p>The particular <code>SchedulerBuilder</code> used will dictate
     * the concrete type of Trigger that is produced by the TriggerBuilder.</p>
     * @param schedBuilder the SchedulerBuilder to use.
     * @return the updated TriggerBuilder
     * @see ScheduleBuilder
     * @see SimpleScheduleBuilder
     * @see CronScheduleBuilder
     * @see CalendarIntervalScheduleBuilder
     * 
     是根据里面,来确定Trigger接口实现类的类型
其中,这个cron里面的解析"0/2 * * * * ?":是通过CronExpression.java中的buildExpression方法来解析的

在CronTriggerImpl中会
@Deprecated
    public CronTriggerImpl(String name, String group, String cronExpression)
        throws ParseException {
        
        super(name, group);//name和group

        setCronExpression(cronExpression);//解析cron字符串

        setStartTime(new Date());//当前时间
        setTimeZone(TimeZone.getDefault());//当前时区
    }

//注册任务和定时器

scheduler.scheduleJob(jobDetail,trigger);
其实是调用的是QuartzScheduler中的 public Date scheduleJob(JobDetail jobDetail,
            Trigger trigger) throws SchedulerException方法

  resources.getJobStore().storeJobAndTrigger(jobDetail, trig);//存储job and trigger到jobStore
        notifySchedulerListenersJobAdded(jobDetail);//添加jobDetail到调度监听器
        notifySchedulerThread(trigger.getNextFireTime().getTime());//通知调度器下一刻调度时间
        notifySchedulerListenersSchduled(trigger);//添加trigger到调度监听器

//启动调度器

 scheduler.start();
 public void start() throws SchedulerException {

        if (shuttingDown|| closed) {
            throw new SchedulerException(
                    "The Scheduler cannot be restarted after shutdown() has been called.");
        }

        // QTZ-212 : calling new schedulerStarting() method on the listeners
        // right after entering start()
        notifySchedulerListenersStarting();//通知调度监听器正在启动

        if (initialStart == null) {
            initialStart = new Date();
            this.resources.getJobStore().schedulerStarted(); //           
            startPlugins();
        } else {
            resources.getJobStore().schedulerResumed();
        }

        schedThread.togglePause(false);

        getLog().info(
                "Scheduler " + resources.getUniqueIdentifier() + " started.");
        
        notifySchedulerListenersStarted();//通知调度监听器已经启动
    }

start()这个方法明天再看,回去看QGhappy vs BA黑凤梨
2018.10.10卖萌日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值