林炳文Evankaka原创作品。转载请注明出处http://blog.youkuaiyun.com/evankaka
Quartz 框架提供了几种用于扩展平台能力的方式。通过使用各种 "钩子" (通常指的就是扩展点),Quartz 变得很容易被扩展和定制化来适应你的需要。其中一个最简单的扩展框架的方法就是使用 Quartz 插件。本章就来看看如何使用插件机制让 Quartz 进入到之前 Quartz 用户没去过的领域。
一、使用Quartz自带插件范例
下面将使用插件实现从XML得到JOB,不用手工的把job和trigger加到Scheduler中去再来运行,这样就很方便。如果要更改任务,直接在xml中配置就可以了。不用再写Java代码。
1、首先是job类:
- package com.mucfc;
- import java.util.Date;
- import java.util.Set;
- import org.quartz.DisallowConcurrentExecution;
- import org.quartz.InterruptableJob;
- import org.quartz.Job;
- import org.quartz.JobDataMap;
- import org.quartz.JobExecutionContext;
- import org.quartz.JobExecutionException;
- import org.quartz.JobKey;
- import org.quartz.PersistJobDataAfterExecution;
- import org.quartz.UnableToInterruptJobException;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- @PersistJobDataAfterExecution
- @DisallowConcurrentExecution
- public class SimpleJob implements Job {
- private static Logger log = LoggerFactory.getLogger(SimpleJob.class);
- private JobKey jobkey=null;
- @Override
- public void execute(JobExecutionContext context) throws JobExecutionException {
- jobkey = context.getJobDetail().getKey();
- log.info("Excuting job: " + jobkey + " executing at " + new Date()+" fire by: "+context.getTrigger().getKey());
- if(context.getMergedJobDataMap().size()>0){
- Set<String> keys= context.getMergedJobDataMap().keySet();
- for (String key : keys) {
- String value= context.getMergedJobDataMap().getString(key);
- log.info(" jobdatamap entry: "+key+" = "+value);
- }
- context.setResult("hello");
- }
- }
- }
2、job触发时间配置,使用quartz_data.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
- version="1.8">
- <pre-processing-commands>
- <delete-jobs-in-group>*</delete-jobs-in-group> <!-- clear all jobs in scheduler -->
- <delete-triggers-in-group>*</delete-triggers-in-group> <!-- clear all triggers in scheduler -->
- </pre-processing-commands>
- <processing-directives>
- <!-- if there are any jobs/trigger in scheduler of same name (as in this file), overwrite them -->
- <overwrite-existing-data>true</overwrite-existing-data>
- <!-- if there are any jobs/trigger in scheduler of same name (as in this file), and over-write is false, ignore them rather then generating an error -->
- <ignore-duplicates>false</ignore-duplicates>
- </processing-directives>
- <schedule>
- <job>
- <name>TestJob1</name>
- <job-class>com.mucfc.SimpleJob</job-class>
- </job>
- <job>
- <name>TestDurableJob</name>
- <job-class>com.mucfc.SimpleJob</job-class>
- <durability>true</durability>
- <recover>false</recover>
- </job>
- <trigger>
- <simple>
- <name>TestSimpleTrigger1AtFiveSecondInterval</name>
- <job-name>TestJob1</job-name>
- <repeat-count>-1</repeat-count> <!-- repeat indefinitely -->
- <repeat-interval>5000</repeat-interval> <!-- every 5 seconds -->
- </simple>
- </trigger>
- <job>
- <name>TestJob2</name>
- <group>GroupOfTestJob2</group>
- <description>This is the description of TestJob2</description>
- <job-class>com.mucfc.SimpleJob</job-class>
- <durability>false</durability>
- <recover>true</recover>
- <job-data-map>
- <entry>
- <key>someKey</key>
- <value>someValue</value>
- </entry>
- <entry>
- <key>someOtherKey</key>
- <value>someOtherValue</value>
- </entry>
- </job-data-map>
- </job>
- <trigger>
- <simple>
- <name>TestSimpleTrigger2AtTenSecondIntervalAndFiveRepeats</name>
- <group>GroupOfTestJob2Triggers</group>
- <job-name>TestJob2</job-name>
- <job-group>GroupOfTestJob2</job-group>
- <start-time>2010-02-09T10:15:00</start-time>
- <misfire-instruction>MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT</misfire-instruction>
- <repeat-count>5</repeat-count>
- <repeat-interval>10000</repeat-interval>
- </simple>
- </trigger>
- <trigger>
- <cron>
- <name>TestCronTrigger2AtEveryMinute</name>
- <group>GroupOfTestJob2Triggers</group>
- <job-name>TestJob2</job-name>
- <job-group>GroupOfTestJob2</job-group>
- <job-data-map>
- <entry>
- <key>someKey</key>
- <value>overriddenValue</value>
- </entry>
- <entry>
- <key>someOtherKey</key>
- <value>someOtherOverriddenValue</value>
- </entry>
- </job-data-map>
- <cron-expression>0 * * ? * *</cron-expression>
- </cron>
- </trigger>
- <trigger>
- <cron>
- <name>TestCronTrigger2AtEveryMinuteOnThe45thSecond</name>
- <group>GroupOfTestJob2Triggers</group>
- <job-name>TestJob2</job-name>
- <job-group>GroupOfTestJob2</job-group>
- <start-time>2015-05-12T12:26:00.0</start-time>
- <end-time>2015-05-16T12:26:00.0</end-time>
- <misfire-instruction>MISFIRE_INSTRUCTION_SMART_POLICY</misfire-instruction>
- <cron-expression>45 * * ? * *</cron-expression>
- <time-zone>America/Los_Angeles</time-zone>
- </cron>
- </trigger>
- </schedule>
- </job-scheduling-data>
3、配置文件
- #============================================================================
- # Configure Main Scheduler Properties
- #============================================================================
- org.quartz.scheduler.instanceName: TestScheduler
- org.quartz.scheduler.instanceId: AUTO
- org.quartz.scheduler.skipUpdateCheck: true
- #============================================================================
- # Configure ThreadPool
- #============================================================================
- org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
- org.quartz.threadPool.threadCount: 3
- org.quartz.threadPool.threadPriority: 5
- #============================================================================
- # Configure JobStore
- #============================================================================
- org.quartz.jobStore.misfireThreshold: 60000
- org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
- #org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
- #org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
- #org.quartz.jobStore.useProperties: false
- #org.quartz.jobStore.dataSource: myDS
- #org.quartz.jobStore.tablePrefix: QRTZ_
- #org.quartz.jobStore.isClustered: false
- #============================================================================
- # Configure Datasources
- #============================================================================
- #org.quartz.dataSource.myDS.driver: org.postgresql.Driver
- #org.quartz.dataSource.myDS.URL: jdbc:postgresql://localhost/dev
- #org.quartz.dataSource.myDS.user: jhouse
- #org.quartz.dataSource.myDS.password:
- #org.quartz.dataSource.myDS.maxConnections: 5
- #============================================================================
- # Configure Plugins
- #============================================================================
- org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin
- org.quartz.plugin.jobInitializer.class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
- org.quartz.plugin.jobInitializer.fileNames: quartz_data.xml
- org.quartz.plugin.jobInitializer.failOnFileNotFound: true
- org.quartz.plugin.jobInitializer.scanInterval: 120
- org.quartz.plugin.jobInitializer.wrapInUserTransaction: false
其中org.quartz.plugin.jobInitializer.class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin会自动加载quartz_data.xml中的trigger和job到Scheduler
3、测试
- package com.mucfc;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.GregorianCalendar;
- import org.quartz.DateBuilder;
- import org.quartz.JobBuilder;
- import org.quartz.JobDetail;
- import org.quartz.Matcher;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerFactory;
- import org.quartz.SchedulerMetaData;
- import org.quartz.SimpleScheduleBuilder;
- import org.quartz.SimpleTrigger;
- import org.quartz.Trigger;
- import org.quartz.TriggerBuilder;
- import org.quartz.impl.StdSchedulerFactory;
- import org.quartz.impl.calendar.AnnualCalendar;
- import org.quartz.impl.matchers.KeyMatcher;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class PluginExample {
- public static void run() throws Exception {
- Logger log = LoggerFactory.getLogger(PluginExample.class);
- SchedulerFactory sf = new StdSchedulerFactory();
- Scheduler sche = sf.getScheduler();
- sche.start();
- try {
- Thread.sleep(300000L);
- } catch (Exception e) {
- }
- sche.shutdown();
- SchedulerMetaData metaData = sche.getMetaData();
- log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
- }
- public static void main(String[] args) {
- PluginExample simpleExample = new PluginExample();
- try {
- simpleExample.run();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
4、结果:
看到了没,不用再把job和trigger手工加到Scheduler中去,它会自动加载XML中定义好的任务,需要做的只是start就行了。
林炳文Evankaka原创作品。转载请注明出处http://blog.youkuaiyun.com/evankaka