quartz实现自定义任务

1、导入quartz、C3p0、MySQL的jar包(懒得找jar包,直接创建springboot工程导入坐标)
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <scope>runtime</scope>
</dependency>
2、先quartz.jar看一下目录下的内容

quartz实现自定义任务

该图中的单节点任务主要是单机版使用到的,下面那个是可以创建集群定时任务调度管理控制环境

quartz实现自定义任务

3、查看调度工厂相关的类

quartz实现自定义任务

该接口有三个方法

// 获取调度器
Scheduler getScheduler() throws SchedulerException;
// 通过名字获取调度器
Scheduler getScheduler(String var1) throws SchedulerException;
// 获取所有的调度器
Collection<Scheduler> getAllSchedulers() throws SchedulerException;

quartz实现自定义任务

该接口有两个实现类,第一个类(推荐大佬,喜欢折腾的去搞),第二个是常见的实现

4、创建工厂类的实现,并获取调度器

quartz实现自定义任务

在该类中可以看到该类有三个构造方法

分别是通过:

默认的方式创建创建

通过读取指定文件名的内容来创建

通过去读取PropertiesParser对象传的数据创建

quartz实现自定义任务

获取调度器

quartz实现自定义任务

当不是通过传入配置文件内容的情况创建的工厂时,会进行工厂初始化,再通过仓库同步创建一个实例,再通过默认的调度器实例名称去仓库查找改名字的的调度器,如果该调度器不为空,再判断改调度器是否关闭,没有关闭的话则返回改调度器,关闭的话,则从仓库移除改调度器;如果调度器为空,则进行实例化

SchedulerRepository的源码如下:

public class SchedulerRepository {
    private HashMap<String, Scheduler> schedulers = new HashMap();
    private static SchedulerRepository inst;

    private SchedulerRepository() {
    }

    public static synchronized SchedulerRepository getInstance() {
        if (inst == null) {
            inst = new SchedulerRepository();
        }

        return inst;
    }

    public synchronized void bind(Scheduler sched) throws SchedulerException {
        if ((Scheduler)this.schedulers.get(sched.getSchedulerName()) != null) {
            throw new SchedulerException("Scheduler with name '" + sched.getSchedulerName() + "' already exists.");
        } else {
            this.schedulers.put(sched.getSchedulerName(), sched);
        }
    }

    public synchronized boolean remove(String schedName) {
        return this.schedulers.remove(schedName) != null;
    }

    public synchronized Scheduler lookup(String schedName) {
        return (Scheduler)this.schedulers.get(schedName);
    }

    public synchronized Collection<Scheduler> lookupAll() {
        return Collections.unmodifiableCollection(this.schedulers.values());
    }
}
5、使用基于数据库的定时任务管理

通过加载自定义配置文件来完成实现

自定义配置文件存放于classpath下

org.quartz.scheduler.instanceName=MyQuartzScheduler
org.quartz.scheduler.dSName=MyDemo
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.provider=C3p0PoolingConnectionProvider
org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/test
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = root
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery = select 1

创建工厂获取调度器代码如下

StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory("myQuartz.properties");

Scheduler scheduler = stdSchedulerFactory.getScheduler();

通过加载自定义配置文件初始化部分源码如下

for(int i = 0; i < dsNames.length; ++i) {
    PropertiesParser pp = new PropertiesParser(this.cfg.getPropertyGroup("org.quartz.dataSource." + dsNames[i], true));
    String cpClass = pp.getStringProperty("connectionProvider.class", (String)null);
    if (cpClass != null) {
		// 代码省略
    } else {
        String dsJndi = pp.getStringProperty("jndiURL", (String)null);
        String dsJndiProvider;
        if (dsJndi != null) {
			// 代码省略
        } else {
            plugInClass = pp.getStringProperty("provider");
            dsJndiInitial = pp.getStringProperty("driver");
            dsJndiProvider = pp.getStringProperty("URL");
            if (dsJndiInitial == null) {
                this.initException = new SchedulerException("Driver not specified for DataSource: " + dsNames[i]);
                throw this.initException;
            }

            if (dsJndiProvider == null) {
                this.initException = new SchedulerException("DB URL not specified for DataSource: " + dsNames[i]);
                throw this.initException;
            }

            if (plugInClass != null && plugInClass.equals("hikaricp")) {
                cpClass = "org.quartz.utils.HikariCpPoolingConnectionProvider";
            } else {
                cpClass = "org.quartz.utils.C3p0PoolingConnectionProvider";
            }

            this.log.info("Using ConnectionProvider class '" + cpClass + "' for data source '" + dsNames[i] + "'");

            try {
                listenerClass = null;

                ConnectionProvider cp;
                try {
                    Constructor constructor = loadHelper.loadClass(cpClass).getConstructor(Properties.class);
                    cp = (ConnectionProvider)constructor.newInstance(pp.getUnderlyingProperties());
                } catch (Exception var75) {
                    this.initException = new SchedulerException("ConnectionProvider class '" + cpClass + "' could not be instantiated.", var75);
                    throw this.initException;
                }

                dbMgr = DBConnectionManager.getInstance();
                dbMgr.addConnectionProvider(dsNames[i], cp);
                this.populateProviderWithExtraProps((PoolingConnectionProvider)cp, pp.getUnderlyingProperties());
            } catch (Exception var76) {
                this.initException = new SchedulerException("Could not initialize DataSource: " + dsNames[i], var76);
                throw this.initException;
            }
        }
    }
}

String[] pluginNames = this.cfg.getPropertyGroups("org.quartz.plugin");
SchedulerPlugin[] plugins = new SchedulerPlugin[pluginNames.length];

// 代码省略

Class<?>[] strArg = new Class[]{String.class};
String[] jobListenerNames = this.cfg.getPropertyGroups("org.quartz.jobListener");
JobListener[] jobListeners = new JobListener[jobListenerNames.length];

// 代码省略

String[] triggerListenerNames = this.cfg.getPropertyGroups("org.quartz.triggerListener");
TriggerListener[] triggerListeners = new TriggerListener[triggerListenerNames.length];

String listenerClass;
// 代码省略

boolean tpInited = false;
boolean qsInited = false;
listenerClass = this.cfg.getStringProperty("org.quartz.threadExecutor.class");
Object threadExecutor;
if (listenerClass != null) {
    tProps = this.cfg.getPropertyGroup("org.quartz.threadExecutor", true);

    try {
        threadExecutor = (ThreadExecutor)loadHelper.loadClass(listenerClass).newInstance();
        this.log.info("Using custom implementation for ThreadExecutor: " + listenerClass);
        this.setBeanProps(threadExecutor, tProps);
    } catch (Exception var68) {
        this.initException = new SchedulerException("ThreadExecutor class '" + listenerClass + "' could not be instantiated.", var68);
        throw this.initException;
    }
} else {
    this.log.info("Using default implementation for ThreadExecutor");
    threadExecutor = new DefaultThreadExecutor();
}

try {
    jrsf = null;
    if (userTXLocation != null) {
        UserTransactionHelper.setUserTxLocation(userTXLocation);
    }

    Object jrsf;
    if (wrapJobInTx) {
        jrsf = new JTAJobRunShellFactory();
    } else {
        jrsf = new JTAAnnotationAwareJobRunShellFactory();
    }

    if (autoId) {
        try {
            schedInstId = "NON_CLUSTERED";
            if (js.isClustered()) {
                schedInstId = instanceIdGenerator.generateInstanceId();
            }
        } catch (Exception var67) {
            this.getLog().error("Couldn't generate instance Id!", var67);
            throw new IllegalStateException("Cannot run without an instance id.");
        }
    }

    if (js.getClass().getName().startsWith("org.terracotta.quartz")) {
        try {
            String uuid = (String)js.getClass().getMethod("getUUID").invoke(js);
            if (schedInstId.equals("NON_CLUSTERED")) {
                schedInstId = "TERRACOTTA_CLUSTERED,node=" + uuid;
                if (jmxObjectName == null) {
                    jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId);
                }
            } else if (jmxObjectName == null) {
                jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId + ",node=" + uuid);
            }
        } catch (Exception var66) {
            throw new RuntimeException("Problem obtaining node id from TerracottaJobStore.", var66);
        }

        if (null == this.cfg.getStringProperty("org.quartz.scheduler.jmx.export")) {
            jmxExport = true;
        }
    }

    if (js instanceof JobStoreSupport) {
        JobStoreSupport jjs = (JobStoreSupport)js;
        jjs.setDbRetryInterval(dbFailureRetry);
        if (threadsInheritInitalizersClassLoader) {
            jjs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);
        }

        jjs.setThreadExecutor((ThreadExecutor)threadExecutor);
    }

    QuartzSchedulerResources rsrcs = new QuartzSchedulerResources();
    rsrcs.setName(schedName);
    rsrcs.setThreadName(threadName);
    rsrcs.setInstanceId(schedInstId);
    rsrcs.setJobRunShellFactory((JobRunShellFactory)jrsf);
    rsrcs.setMakeSchedulerThreadDaemon(makeSchedulerThreadDaemon);
    rsrcs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);
    rsrcs.setBatchTimeWindow(batchTimeWindow);
    rsrcs.setMaxBatchSize(maxBatchSize);
    rsrcs.setInterruptJobsOnShutdown(interruptJobsOnShutdown);
    rsrcs.setInterruptJobsOnShutdownWithWait(interruptJobsOnShutdownWithWait);
    rsrcs.setJMXExport(jmxExport);
    rsrcs.setJMXObjectName(jmxObjectName);
    if (managementRESTServiceEnabled) {
        ManagementRESTServiceConfiguration managementRESTServiceConfiguration = new ManagementRESTServiceConfiguration();
        managementRESTServiceConfiguration.setBind(managementRESTServiceHostAndPort);
        managementRESTServiceConfiguration.setEnabled(managementRESTServiceEnabled);
        rsrcs.setManagementRESTServiceConfiguration(managementRESTServiceConfiguration);
    }

    if (rmiExport) {
        rsrcs.setRMIRegistryHost(rmiHost);
        rsrcs.setRMIRegistryPort(rmiPort);
        rsrcs.setRMIServerPort(rmiServerPort);
        rsrcs.setRMICreateRegistryStrategy(rmiCreateRegistry);
        rsrcs.setRMIBindName(rmiBindName);
    }

    SchedulerDetailsSetter.setDetails(tp, schedName, schedInstId);
    rsrcs.setThreadExecutor((ThreadExecutor)threadExecutor);
    ((ThreadExecutor)threadExecutor).initialize();
    rsrcs.setThreadPool(tp);
    if (tp instanceof SimpleThreadPool && threadsInheritInitalizersClassLoader) {
        ((SimpleThreadPool)tp).setThreadsInheritContextClassLoaderOfInitializingThread(threadsInheritInitalizersClassLoader);
    }

    tp.initialize();
    tpInited = true;
    rsrcs.setJobStore(js);

    for(int i = 0; i < plugins.length; ++i) {
        rsrcs.addSchedulerPlugin(plugins[i]);
    }

    qs = new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry);
    qsInited = true;
    Scheduler scheduler = this.instantiate(rsrcs, qs);
    if (jobFactory != null) {
        qs.setJobFactory(jobFactory);
    }

    int i;
    for(i = 0; i < plugins.length; ++i) {
        plugins[i].initialize(pluginNames[i], scheduler, loadHelper);
    }

    for(i = 0; i < jobListeners.length; ++i) {
        qs.getListenerManager().addJobListener(jobListeners[i], EverythingMatcher.allJobs());
    }

    for(i = 0; i < triggerListeners.length; ++i) {
        qs.getListenerManager().addTriggerListener(triggerListeners[i], EverythingMatcher.allTriggers());
    }

    Iterator i$ = schedCtxtProps.keySet().iterator();

    while(i$.hasNext()) {
        Object key = i$.next();
        String val = schedCtxtProps.getProperty((String)key);
        scheduler.getContext().put((String)key, val);
    }

    js.setInstanceId(schedInstId);
    js.setInstanceName(schedName);
    js.setThreadPoolSize(tp.getPoolSize());
    js.initialize(loadHelper, qs.getSchedulerSignaler());
    ((JobRunShellFactory)jrsf).initialize(scheduler);
    qs.initialize();
    this.getLog().info("Quartz scheduler '" + scheduler.getSchedulerName() + "' initialized from " + this.propSrc);
    this.getLog().info("Quartz scheduler version: " + qs.getVersion());
    qs.addNoGCObject(schedRep);
    if (dbMgr != null) {
        qs.addNoGCObject(dbMgr);
    }

    schedRep.bind(scheduler);

创建任务详情

JobDetail build1 = newJob(MyJob.class).withIdentity("testJob", "testJobGroup").usingJobData(new JobDataMap()).build();



public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        System.out.println("任务执行了 ===================== ");
        System.out.println("jobDataMap = " + jobDataMap);
    }
}

查看任务构建类源码

quartz实现自定义任务

JobBuilder类的部分源码如下

public class JobBuilder {
    private JobKey key;
    private String description;
    private Class<? extends Job> jobClass;
    private boolean durability;
    private boolean shouldRecover;
    private JobDataMap jobDataMap = new JobDataMap();
    
    public static JobBuilder newJob(Class<? extends Job> jobClass) {
        JobBuilder b = new JobBuilder();
        b.ofType(jobClass);
        return b;
    }

    public JobDetail build() {
        JobDetailImpl job = new JobDetailImpl();
        job.setJobClass(this.jobClass);
        job.setDescription(this.description);
        if (this.key == null) {
            this.key = new JobKey(Key.createUniqueName((String)null), (String)null);
        }

        job.setKey(this.key);
        job.setDurability(this.durability);
        job.setRequestsRecovery(this.shouldRecover);
        if (!this.jobDataMap.isEmpty()) {
            job.setJobDataMap(this.jobDataMap);
        }

        return job;
    }

    public JobBuilder withIdentity(String name) {
        this.key = new JobKey(name, (String)null);
        return this;
    }

    public JobBuilder withIdentity(String name, String group) {
        this.key = new JobKey(name, group);
        return this;
    }

    public JobBuilder withIdentity(JobKey jobKey) {
        this.key = jobKey;
        return this;
    }

    public JobBuilder withDescription(String jobDescription) {
        this.description = jobDescription;
        return this;
    }

    public JobBuilder ofType(Class<? extends Job> jobClazz) {
        this.jobClass = jobClazz;
        return this;
    }

    public JobBuilder requestRecovery() {
        this.shouldRecover = true;
        return this;
    }

    public JobBuilder requestRecovery(boolean jobShouldRecover) {
        this.shouldRecover = jobShouldRecover;
        return this;
    }

    public JobBuilder storeDurably() {
        return this.storeDurably(true);
    }

    public JobBuilder storeDurably(boolean jobDurability) {
        this.durability = jobDurability;
        return this;
    }

    public JobBuilder usingJobData(String dataKey, String value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(String dataKey, Integer value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(String dataKey, Long value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(String dataKey, Float value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(String dataKey, Double value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(String dataKey, Boolean value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public JobBuilder usingJobData(JobDataMap newJobDataMap) {
        this.jobDataMap.putAll(newJobDataMap);
        return this;
    }

    public JobBuilder setJobData(JobDataMap newJobDataMap) {
        this.jobDataMap = newJobDataMap;
        return this;
    }

创建任务触发器

CronTrigger build = TriggerBuilder.newTrigger()
        .withIdentity("test", "testGroup")
        .withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?").withMisfireHandlingInstructionDoNothing())
        .usingJobData(new JobDataMap()).build();

查看触发器构建类

quartz实现自定义任务

该类源码如下

public class TriggerBuilder<T extends Trigger> {
    private TriggerKey key;
    private String description;
    private Date startTime = new Date();
    private Date endTime;
    private int priority = 5;
    private String calendarName;
    private JobKey jobKey;
    private JobDataMap jobDataMap = new JobDataMap();
    private ScheduleBuilder<?> scheduleBuilder = null;

    private TriggerBuilder() {
    }

    public static TriggerBuilder<Trigger> newTrigger() {
        return new TriggerBuilder();
    }

    public T build() {
        if (this.scheduleBuilder == null) {
            this.scheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
        }

        MutableTrigger trig = this.scheduleBuilder.build();
        trig.setCalendarName(this.calendarName);
        trig.setDescription(this.description);
        trig.setStartTime(this.startTime);
        trig.setEndTime(this.endTime);
        if (this.key == null) {
            this.key = new TriggerKey(Key.createUniqueName((String)null), (String)null);
        }

        trig.setKey(this.key);
        if (this.jobKey != null) {
            trig.setJobKey(this.jobKey);
        }

        trig.setPriority(this.priority);
        if (!this.jobDataMap.isEmpty()) {
            trig.setJobDataMap(this.jobDataMap);
        }

        return trig;
    }

    public TriggerBuilder<T> withIdentity(String name) {
        this.key = new TriggerKey(name, (String)null);
        return this;
    }

    public TriggerBuilder<T> withIdentity(String name, String group) {
        this.key = new TriggerKey(name, group);
        return this;
    }

    public TriggerBuilder<T> withIdentity(TriggerKey triggerKey) {
        this.key = triggerKey;
        return this;
    }

    public TriggerBuilder<T> withDescription(String triggerDescription) {
        this.description = triggerDescription;
        return this;
    }

    public TriggerBuilder<T> withPriority(int triggerPriority) {
        this.priority = triggerPriority;
        return this;
    }

    public TriggerBuilder<T> modifiedByCalendar(String calName) {
        this.calendarName = calName;
        return this;
    }

    public TriggerBuilder<T> startAt(Date triggerStartTime) {
        this.startTime = triggerStartTime;
        return this;
    }

    public TriggerBuilder<T> startNow() {
        this.startTime = new Date();
        return this;
    }

    public TriggerBuilder<T> endAt(Date triggerEndTime) {
        this.endTime = triggerEndTime;
        return this;
    }

    public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder) {
        this.scheduleBuilder = schedBuilder;
        return this;
    }

    public TriggerBuilder<T> forJob(JobKey keyOfJobToFire) {
        this.jobKey = keyOfJobToFire;
        return this;
    }

    public TriggerBuilder<T> forJob(String jobName) {
        this.jobKey = new JobKey(jobName, (String)null);
        return this;
    }

    public TriggerBuilder<T> forJob(String jobName, String jobGroup) {
        this.jobKey = new JobKey(jobName, jobGroup);
        return this;
    }

    public TriggerBuilder<T> forJob(JobDetail jobDetail) {
        JobKey k = jobDetail.getKey();
        if (k.getName() == null) {
            throw new IllegalArgumentException("The given job has not yet had a name assigned to it.");
        } else {
            this.jobKey = k;
            return this;
        }
    }

    public TriggerBuilder<T> usingJobData(String dataKey, String value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Integer value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Long value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Float value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Double value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Boolean value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(JobDataMap newJobDataMap) {
        Iterator i$ = this.jobDataMap.keySet().iterator();

        while(i$.hasNext()) {
            String dataKey = (String)i$.next();
            newJobDataMap.put(dataKey, this.jobDataMap.get(dataKey));
        }

        this.jobDataMap = newJobDataMap;
        return this;
    }
}

通过上面的源码中的withSchedule(ScheduleBuilder schedBuilder)可知该类需要一个ScheduleBuilder的对象参数

查看ScheduleBuilderde类的源码

public class TriggerBuilder<T extends Trigger> {
    private TriggerKey key;
    private String description;
    private Date startTime = new Date();
    private Date endTime;
    private int priority = 5;
    private String calendarName;
    private JobKey jobKey;
    private JobDataMap jobDataMap = new JobDataMap();
    private ScheduleBuilder<?> scheduleBuilder = null;

    private TriggerBuilder() {
    }

    public static TriggerBuilder<Trigger> newTrigger() {
        return new TriggerBuilder();
    }

    public T build() {
        if (this.scheduleBuilder == null) {
            this.scheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
        }

        MutableTrigger trig = this.scheduleBuilder.build();
        trig.setCalendarName(this.calendarName);
        trig.setDescription(this.description);
        trig.setStartTime(this.startTime);
        trig.setEndTime(this.endTime);
        if (this.key == null) {
            this.key = new TriggerKey(Key.createUniqueName((String)null), (String)null);
        }

        trig.setKey(this.key);
        if (this.jobKey != null) {
            trig.setJobKey(this.jobKey);
        }

        trig.setPriority(this.priority);
        if (!this.jobDataMap.isEmpty()) {
            trig.setJobDataMap(this.jobDataMap);
        }

        return trig;
    }

    public TriggerBuilder<T> withIdentity(String name) {
        this.key = new TriggerKey(name, (String)null);
        return this;
    }

    public TriggerBuilder<T> withIdentity(String name, String group) {
        this.key = new TriggerKey(name, group);
        return this;
    }

    public TriggerBuilder<T> withIdentity(TriggerKey triggerKey) {
        this.key = triggerKey;
        return this;
    }

    public TriggerBuilder<T> withDescription(String triggerDescription) {
        this.description = triggerDescription;
        return this;
    }

    public TriggerBuilder<T> withPriority(int triggerPriority) {
        this.priority = triggerPriority;
        return this;
    }

    public TriggerBuilder<T> modifiedByCalendar(String calName) {
        this.calendarName = calName;
        return this;
    }

    public TriggerBuilder<T> startAt(Date triggerStartTime) {
        this.startTime = triggerStartTime;
        return this;
    }

    public TriggerBuilder<T> startNow() {
        this.startTime = new Date();
        return this;
    }

    public TriggerBuilder<T> endAt(Date triggerEndTime) {
        this.endTime = triggerEndTime;
        return this;
    }

    public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder) {
        this.scheduleBuilder = schedBuilder;
        return this;
    }

    public TriggerBuilder<T> forJob(JobKey keyOfJobToFire) {
        this.jobKey = keyOfJobToFire;
        return this;
    }

    public TriggerBuilder<T> forJob(String jobName) {
        this.jobKey = new JobKey(jobName, (String)null);
        return this;
    }

    public TriggerBuilder<T> forJob(String jobName, String jobGroup) {
        this.jobKey = new JobKey(jobName, jobGroup);
        return this;
    }

    public TriggerBuilder<T> forJob(JobDetail jobDetail) {
        JobKey k = jobDetail.getKey();
        if (k.getName() == null) {
            throw new IllegalArgumentException("The given job has not yet had a name assigned to it.");
        } else {
            this.jobKey = k;
            return this;
        }
    }

    public TriggerBuilder<T> usingJobData(String dataKey, String value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Integer value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Long value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Float value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Double value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(String dataKey, Boolean value) {
        this.jobDataMap.put(dataKey, value);
        return this;
    }

    public TriggerBuilder<T> usingJobData(JobDataMap newJobDataMap) {
        Iterator i$ = this.jobDataMap.keySet().iterator();

        while(i$.hasNext()) {
            String dataKey = (String)i$.next();
            newJobDataMap.put(dataKey, this.jobDataMap.get(dataKey));
        }

        this.jobDataMap = newJobDataMap;
        return this;
    }
}

通过上图源码的可知该类泛型继承了trigger接口,trigger接口 的继承、实现的类如下

quartz实现自定义任务

改类的withSchedule(ScheduleBuilder schedBuilder)的返回类型泛型SBT继承了T,间接继承了trigger

查看JobDataMap类的源码

quartz实现自定义任务

根据实现图可知,该类间接的实现了Map接口,所以该类有Map的方法的实现

进而得知该类的存放的数据是key-value形式的

部分源码如下

public class JobDataMap extends StringKeyDirtyFlagMap implements Serializable {
    private static final long serialVersionUID = -6939901990106713909L;

    public JobDataMap() {
        super(15);
    }

    public JobDataMap(Map<?, ?> map) {
        this();
        this.putAll(map);
        this.clearDirtyFlag();
    }

    public void putAsString(String key, boolean value) {
        String strValue = Boolean.valueOf(value).toString();
        super.put(key, strValue);
    }

    public void putAsString(String key, Boolean value) {
        String strValue = value.toString();
        super.put(key, strValue);
    }

    public void putAsString(String key, char value) {
        String strValue = Character.valueOf(value).toString();
        super.put(key, strValue);
    }

    public void putAsString(String key, Character value) {
        String strValue = value.toString();
        super.put(key, strValue);
    }

    public void putAsString(String key, double value) {
        String strValue = Double.toString(value);
        super.put(key, strValue);
    }

    public void putAsString(String key, Double value) {
        String strValue = value.toString();
        super.put(key, strValue);
    }
}

调度任务

scheduler.scheduleJob(build1,build);

源码如下:

public Date scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {
    this.validateState();
    if (jobDetail == null) {
        throw new SchedulerException("JobDetail cannot be null");
    } else if (trigger == null) {
        throw new SchedulerException("Trigger cannot be null");
    } else if (jobDetail.getKey() == null) {
        throw new SchedulerException("Job's key cannot be null");
    } else if (jobDetail.getJobClass() == null) {
        throw new SchedulerException("Job's class cannot be null");
    } else {
        OperableTrigger trig = (OperableTrigger)trigger;
        if (trigger.getJobKey() == null) {
            trig.setJobKey(jobDetail.getKey());
        } else if (!trigger.getJobKey().equals(jobDetail.getKey())) {
            throw new SchedulerException("Trigger does not reference given job!");
        }

        trig.validate();
        Calendar cal = null;
        if (trigger.getCalendarName() != null) {
            cal = this.resources.getJobStore().retrieveCalendar(trigger.getCalendarName());
        }

        Date ft = trig.computeFirstFireTime(cal);
        if (ft == null) {
            throw new SchedulerException("Based on configured schedule, the given trigger '" + trigger.getKey() + "' will never fire.");
        } else {
            this.resources.getJobStore().storeJobAndTrigger(jobDetail, trig);
            this.notifySchedulerListenersJobAdded(jobDetail);
            this.notifySchedulerThread(trigger.getNextFireTime().getTime());
            this.notifySchedulerListenersSchduled(trigger);
            return ft;
        }
    }
}

开启调度器

scheduler.start();

源码如下:

public void start() throws SchedulerException {
    if (!this.shuttingDown && !this.closed) {
        this.notifySchedulerListenersStarting();
        if (this.initialStart == null) {
            this.initialStart = new Date();
            this.resources.getJobStore().schedulerStarted();
            this.startPlugins();
        } else {
            this.resources.getJobStore().schedulerResumed();
        }

        this.schedThread.togglePause(false);
        this.getLog().info("Scheduler " + this.resources.getUniqueIdentifier() + " started.");
        this.notifySchedulerListenersStarted();
    } else {
        throw new SchedulerException("The Scheduler cannot be restarted after shutdown() has been called.");
    }
}

基于数据库的定时任务相关的数据库的创建语句quartz的jar包的目录下

在org.quartz.impl.jdbcjobstore目录下

quartz实现自定义任务

复制对应sql文件下的创建数据表的语句在自己的数据执行创建即可

上一篇:分布式任务调度


下一篇:Quartz框架之简单介绍及使用