精华内容
下载资源
问答
  • Java 定时任务quartz实现方式

    千次阅读 2020-04-30 11:28:44
    Java 定时任务quartz1. java自带 java.util.Timer 实现定时任务2. 使用线程池(ScheduledThreadPool-java.util.concurrent.ScheduledExecutorService)实现定时任务3. 使用注解@Scheduled实现定时任务4. 使用Quartz...

    1. java自带 java.util.Timer 实现定时任务

    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println("schedule--------------" + System.currentTimeMillis());
        }
    }, 10 * 1000, 3 * 1000);// 10秒后执行,执行频率为3秒一次
    
    • schedule(TimerTask task, Date time):安排在指定的时间执行指定的任务。
    • schedule(TimerTask task, Date firstTime, long period) :安排指定的任务在指定的时间开始进行重复的固定延迟执行。
    • schedule(TimerTask task, long delay) :安排在指定延迟后执行指定的任务。
    • schedule(TimerTask task, long delay, long period) :安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
    • scheduleAtFixedRate(TimerTask task, Date firstTime, long period):安排指定的任务在指定的时间开始进行重复的固定速率执行。
    • scheduleAtFixedRate(TimerTask task, long delay, long period):安排指定的任务在指定的延迟后开始进行重复的固定速率执行。

    2. 使用线程池(ScheduledThreadPool-java.util.concurrent.ScheduledExecutorService)实现定时任务

    ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
    service.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            System.out.println("--------------" + System.currentTimeMillis());
        }
    }, 10, 3, TimeUnit.SECONDS);// 10秒后执行,执行频率为3秒一次
    

    3. 使用注解@Scheduled实现定时任务

    注解@Scheduled属性有:

    1. cron : cron的表达式
    2. zone : 解析cron表达式的时区
    3. fixedDelay : 方法之间以毫秒为单位执行带注释的方法,返回延迟,以毫秒为单位
    4. fixedDelayString : 方法之间以毫秒为单位执行带注释的方法,返回延迟,以毫秒为单位
    5. fixedRate : 周期(以毫秒为单位)
    6. fixedRateString : 周期(以毫秒为单位)
    7. initialDelay : 在第一次执行a之前要延迟的毫秒数,初始延迟(以毫秒为单位)
    8. initialDelayString : 在第一次执行a之前要延迟的毫秒数,初始延迟(以毫秒为单位)
    @Component
    public class SpringScheduled {
        // 10秒后开始执行,每隔3秒执行一次
        @Scheduled(initialDelay = 10 * 1000, fixedRate = 3 * 1000)
        public void execute() {
            System.out.println("------------" + System.currentTimeMillis());
        }
    }
    

    4. 使用Quartz定时任务调度器

    4.1 Quartz 特点

    1. 具有强大的调度功能,与Spring容易集成,形成灵活的调度功能。
    2. 调度环境的持久化机制:可以保存并恢复调度现场,即使系统因为故障关闭,任务调度现场的数据并不会丢失。
    3. 灵活的应用方式:可以灵活的定义触发器调度时间表,并可对触发器与任务进行关联映射(通过Name和Group形式为一个的JobKey)。
    4. 分布式与集群能力

    4.2 核心概念

          Quartz核心概念包括:调度器(Scheduler)、任务(Job)、触发器(Trigger)。

          任务:表示一个具体的可执行的调度程序,Job (实现Job接口的具体类)是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

          调度器:一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

          触发器:可配置调度参数。

    4.3 常用对象

    1. Job:一个接口,只有一个 execute(JobExecutionContext context) 方法,用于编写具体的任务业务逻辑。当调度器需要执行 job 时创建实例,调用完成后释放 job 实例。
    2. JobDetail:描述 Job 实列的详细信息。name:job名称;group:job组。默认值为default;jobClass:job接口实现类的class;jobDataMap:存储Job实例的状态信息,调度器使用这些信息添加 Job 实例。
    3. JobExecutionContext:Job能通过 JobExecutionContext 访问 Quartz 运行环境以及 Job 的明细数据,当 Scheduler 调用 Job 时能将数据传递给 execute() 方法。
    4. JobDataMap:是一个JDK中Map接口实例,在任务调度时存在于 JobExecutionContext 中,可将参数对象传递给在运行的 Job 实例;而且,它自身有方便的方法可存取基本数据类型。
    5. Trigger:触发器,可设置首次被触发事件 startTime,不再被触发事件 endTime。
    6. ScheduleBuilder:设置任务执行计划,如多久执行一次,是否重复执行,延迟多久执行等。
    7. Scheduler:调度器,管理任务调取容器。

    4.4 实例代码

    创建一个 Job 实现类,用于编写具体业务逻辑

    import org.quartz.*;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class TestJob implements Job {
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            LocalDateTime nowTime = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
            System.out.println("---------" + formatter.format(nowTime));
            // 获取Scheduler
            Scheduler scheduler = context.getScheduler();
            // 获取Trigger
            Trigger trigger = context.getTrigger();
            // 通过Trigger获取JobDataMap参数
            JobDataMap triggerJobData = trigger.getJobDataMap();
            // 获取JobDetail
            JobDetail jobDetail = context.getJobDetail();
            // 通过JobDetail获取JobDetail参数
            JobDataMap jobDetailData = jobDetail.getJobDataMap();
            // 合并获取JobDataMap,存在键值相同的,取Trigger JobDataMap的值
            JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
        }
    }
    

    具体调度实现代码

    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class TestScheduled {
        public static void main(String[] args) throws SchedulerException {
            // 创建一个Trigger实例
            JobDataMap triggerData = new JobDataMap();
            triggerData.put("trigger1", "我是trigger1");
            triggerData.put("trigger2", "我是trigger2");
            // 创建一个Schedule实例(每个10秒执行一次)
            ScheduleBuilder scheduleBuilder =  CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
            /*ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder
                    .repeatSecondlyForever(10)   //每个10秒执行一次
                    .repeatForever();   //重复执行*/
            Trigger trigger = TriggerBuilder.newTrigger()   // 获取trigger类
                    .withIdentity("triggerName", "triggerGroup")    // 任务唯一标识和组别
                    .withDescription("triggerDescription")  // 描述
                    .usingJobData(triggerData)   // 自定义参数
                    .startNow() // 立即执行,startAt(Date triggerStartTime) -> 某个特定时间开始执行
                                // endAt(Date triggerEndTime) -> 某个特定时间结束执行
                    .withSchedule(scheduleBuilder)  // 设置执行计划
                    .build();
            // 创建一个jobDetil实例,该实例与 Job Class绑定
            JobDataMap jobData = new JobDataMap();
            jobData.put("job1", "我是job1");
            jobData.put("job2", "我是job2");
            JobDetail jobDetail = JobBuilder.newJob(TestJob.class)
                    .withIdentity("jobName", "jobGroup")
                    .withDescription("jobDescription")
                    .usingJobData(jobData)
                    .build();
            // 创建Scheduler实例:javaWeb项目可以通过注入方式创建Scheduler实例,如(@Autowired private Scheduler scheduler;)
            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            Scheduler scheduler = schedulerFactory.getScheduler();
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();  // 执行
        }
    }
    

    4.5 具体对象和方法

    4.5.1 ScheduleBuilder的具体对象和常用方法:

    1. CronScheduleBuilder(常用):它为触发器定义了基于 cronexpress 的调度。该对象的主要通过 Cron表达式 来进行创建,底层代码基本都是将对应参数转换为 Cron表达式 后进行创建。

    • cronSchedule(String cronExpression):通过指定 Cron表达式 创建对象

    2. SimpleScheduleBuilder:它为触发器定义了基于严格/文字间隔的调度。能指定触发的间隔时间和执行次数;

    • build():构建实际的触发器
    • simpleSchedule():static 方法,获取一个 SimpleScheduleBuilder 对象
    • repeatForever():指定触发器将无限重复。
    • withRepeatCount(int triggerRepeatCount):设置重复执行次数
    • repeat___lyForever():设置对应时间单位执行一次,无限重复
    • repeat___lyForever(int):设置当前 对应时间单位 * int 执行一次,无限重复
    • withIntervalIn____s(int/long):根据对应时间单位设置执行间隔

    3. CalendarIntervalScheduleBuilder:它为触发器定义基于间隔的日历时间(天、周、月、年)调度。

    • build():构建实际的触发器
    • calendarIntervalSchedule():创建一个 CalendarIntervalScheduleBuilder。
    • preserveHourOfDayAcrossDaylightSavings(boolean preserveHourOfDay):如果间隔是一天或更长的时间,这个属性(设置为 true )将导致触发器的触发总是在一天的同一时间发生,( startTime 的时间),而不考虑夏令时转换。
    • withInterval(int timeInterval, DateBuilder.IntervalUnit unit):指定要生成的触发器的时间单位和间隔。
    • withIntervalIn___s(int intervalInDays):在 IntervalUnit 中指定一个 interval。所产生的触发器将重复对应时间单位。

    4. DailyTimeIntervalScheduleBuilder:此生成器为您提供了一个额外的方便方法来设置触发器的 endTimeOfDay。

    • build():构建实际的触发器
    • dailyTimeIntervalSchedule():创建一个 DailyTimeIntervalScheduleBuilder。
    • endingDailyAfterCount(int count):使用 count、interval 和 starTimeOfDay 计算和设置 endTimeOfDay。
    • endingDailyAt(TimeOfDay timeOfDay):设置此触发器的每日开始时间,以在给定的时间结束每天的触发。
    • onDaysOfTheWeek(onDaysOfWeek):将触发器设置为在一周中的特定日期触发。
    • onEveryDay():触发时间为一周中的任何一天。
    • onMondayThroughFriday():把周一到周五的日子设为触发时间。
    • onSaturdayAndSunday():触发时间为星期六和星期天。
    • startingDailyAt(TimeOfDay timeOfDay):设置触发开始每天在给定的时间。
    • withInterval(int timeInterval, DateBuilder.IntervalUnit unit):指定要生成的触发器的时间单位和间隔。
    • withIntervalIn____s(int):在 IntervalUnit 中指定一个 interval。所产生的触发器将重复的时间。
    • withRepeatCount(int repeatCount):设置间隔重复的次数。

    4.5.2 TriggerBuilder

          用于实例化触发器。构建器将始终保持自身处于有效状态,并为随时调用 build() 设置合理的缺省值。

    • newTrigger():创建一个新的 TriggerBuilder,用于定义触发器的规范。
    • build():构建触发器
    • endAt(Date triggerEndTime):设置触发器不再触发的时间——即使它的时间表还有剩余的重复。
    • startAt(Date triggerStartTime):根据为触发器配置的计划,设置触发器应该启动的时间——触发器可能启动,也可能不启动。
    • startNow():将触发器应该启动的时间设置为当前时刻—触发器可能启动,也可能不启动—这取决于为触发器配置的调度。
    • forJob:设置生成的触发器触发的作业的标识。
    • modifiedByCalendar(String calName):设置应该应用于此触发器的日程安排的日历的名称。
    • usingJobData:设置触发器的 JobDataMap。
    • withDescription(String triggerDescription):设置给定的(有意义的)触发器描述。
    • withIdentity:使用具有给定名称和组的 TriggerKey 来标识触发器。
    • withPriority(int triggerPriority):设置触发器的优先级。
    • withSchedule(ScheduleBuilder<SBT> schedBuilder):设置 ScheduleBuilder,它将用于定义触发器的调度。

    4.5.3 Scheduler

          这是Quartz调度器的主接口

          调度器维护 JobDetails 和触发器的注册表。一旦注册,调度器就负责在相关的触发器触发时(当它们的计划时间到达时)执行作业。

          Scheduler 实例由 SchedulerFactory 生成。已经创建/初始化的调度器可以通过生成它的工厂找到并使用。创建调度器之后,它处于“备用”模式,必须先调用其 start() 方法,然后才会触发任何作业。

          作业将由“客户端程序”创建,方法是定义一个实现作业接口的类。然后创建 JobDetail 对象(也由客户机创建)来定义作业的单个实例。然后,可以通过 scheduleJob(JobDetail,Trigger)addJob(JobDetail, boolean)方法向调度器注册JobDetail实例。

          然后可以定义触发器来根据给定的调度触发单个作业实例。SimpleTrigger 对于一次性触发非常有用,或者在某个特定的时刻触发,在它们之间有一个给定的延迟,可以重复 N 次。CronTrigger 允许基于日、周、月、月的时间进行调度。

          作业和触发器具有与它们关联的名称和组,这些名称和组应该在单个调度器中惟一地标识它们。“组”功能对于创建作业和 Triggerss 的逻辑分组或分类可能很有用。如果您不需要为给定的触发器作业分配组,那么您可以使用这个接口上定义的 DEFAULT_GROUP 常量。

          存储的作业也可以通过 triggerJob(String jobName, String jobGroup) 函数“手动”触发。

          客户端程序也可能对 Quartz 提供的“listener”接口感兴趣。JobListener 接口提供作业执行的通知。TriggerListener接口提供触发器触发的通知。SchedulerListener 接口提供调度器事件和错误的通知。侦听器可以通过 ListenerManager 接口与本地调度器关联。

    • addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers):将给定的日历添加(注册)到调度程序。
    • addJob(JobDetail jobDetail, boolean replace):将给定的作业添加到调度器—没有关联的触发器。
    • checkExists(JobKey jobKey):确定调度程序中是否已经存在具有给定标识符的作业。
    • checkExists(TriggerKey triggerKey):确定调度程序中是否已经存在具有给定标识符的触发器。
    • clear():清除(删除!)所有调度数据-所有作业,触发日历。
    • deleteCalendar(String calName):从调度程序中删除已标识的日历
    • deleteJob(JobKey jobKey):从调度程序中删除已标识的作业—以及任何关联的触发器。
    • deleteJobs(List<JobKey> jobKeys):从调度程序中删除已标识的作业—以及任何关联的触发器。
    • getCalendar(String calName):获取具有给定名称的日历实例。
    • getCalendarNames():获取所有已注册日历的名称。
    • getContext():返回调度器的调度器上下文。
    • getCurrentlyExecutingJobs():返回 JobExecutionContext 对象的列表,这些对象表示当前在此调度器实例中执行的所有作业。
    • getJobDetail(JobKey jobKey):使用给定的键获取作业实例的 JobDetail。
    • getJobGroupNames():获取所有已知 JobDetail 组的名称。
    • getJobKeys(GroupMatcher<JobKey> matcher):获取匹配组中所有 JobDetails 的键。
    • getListenerManager():获取调度程序的 ListenerManager 的引用,可以通过该引用注册侦听器。
    • getMetaData():获取描述调度器实例的设置和功能的 SchedulerMetaData 对象。
    • getPausedTriggerGroups():获取所有暂停的触发组的名称。
    • getSchedulerInstanceId():返回调度程序的实例Id。
    • getSchedulerName():返回调度程序的名称。
    • getTrigger(TriggerKey triggerKey):使用给定的键获取触发器实例。
    • getTriggerGroupNames():获取所有已知触发器组的名称。
    • getTriggerKeys(GroupMatcher<TriggerKey> matcher):获取给定组中所有触发器的名称。
    • getTriggerKeys(GroupMatcher<TriggerKey> matcher):获取给定组中所有触发器的名称。
    • getTriggersOfJob(JobKey jobKey):获取与标识的 JobDetail 关联的所有触发器。
    • getTriggerState(TriggerKey triggerKey):获取标识的触发器的当前状态。
    • interrupt(JobKey jobKey):在这个调度器实例中,请求中断标识的作业的所有当前正在执行的实例,这些实例必须是 InterruptableJob 接口的实现者。
    • interrupt(String fireInstanceId):在这个调度器实例中请求标识的正在执行的作业实例的中断,该实例必须是 InterruptableJob 接口的实现者。
    • isInStandbyMode():报告调度程序是否处于备用模式。
    • isShutdown():报告调度程序是否已关闭。
    • isStarted():调度程序是否已启动。
    • pauseAll():暂停所有触发器——类似于在每个组上调用 pauseTriggerGroup(group),但是,在使用此方法之后,必须调用 resumeAll() 来清除调度器的“记住”状态,即所有新触发器将在添加时暂停。
    • pauseJob(JobKey jobKey):使用给定的键暂停 JobDetail ——通过暂停它的所有当前触发器。
    • pauseJobs(GroupMatcher<JobKey> matcher):暂停匹配组中的所有 JobDetails—通过暂停它们的所有触发器。
    • pauseTrigger(TriggerKey triggerKey):使用给定的键暂停触发器。
    • pauseTriggers(GroupMatcher<TriggerKey> matcher):暂停匹配组中的所有触发器。
    • rescheduleJob(TriggerKey triggerKey, Trigger newTrigger):使用给定的键删除触发器,并存储新的给定的触发器——它必须与相同的作业相关联(新的触发器必须指定作业名称和组)——但是,新的触发器不需要与旧的触发器具有相同的名称。
    • resumeAll():恢复(非暂停)所有触发器-类似于调用 resumeTriggerGroup(组) 对每个组。
    • resumeJob(JobKey jobKey):使用给定的键恢复(取消暂停) JobDetail。
    • resumeJobs(GroupMatcher<JobKey> matcher):恢复(非暂停)匹配组中的所有 JobDetails。
    • resumeTrigger(TriggerKey triggerKey):使用给定的键恢复(取消暂停)触发器。
    • resumeTriggers(GroupMatcher<TriggerKey> matcher):恢复(取消暂停)匹配组中的所有触发器。
    • scheduleJob(JobDetail jobDetail, Trigger trigger):将给定的 JobDetail 添加到调度器中,并将给定的触发器与之关联。
    • scheduleJob(Trigger trigger):使用由触发器的设置标识的作业调度给定的触发器。
    • scheduleJobs(Map<JobDetail,List<Trigger>> triggersAndJobs, boolean replace):使用相关的一组触发器调度所有给定的作业。
    • setJobFactory(JobFactory factory):设置负责生成作业类实例的 JobFactory。
    • shutdown():停止调度器的触发器触发,并清理与调度器关联的所有资源。
    • shutdown(boolean waitForJobsToComplete):停止调度器的触发器触发,并清理与调度器关联的所有资源。根据 waitForJobsToComplete 判断是否等全部任务执行完后再停止、清理
    • standby():暂时停止调度程序的触发器触发。
    • start():启动引发触发器的调度器线程。
    • startDelayed(int seconds):在指定的秒数之后调用 {#start()}。
    • triggerJob(JobKey jobKey):触发标识的 JobDetail (现在执行它)。
    • triggerJob(JobKey jobKey, JobDataMap data):触发标识的 JobDetail (现在执行它)。并传递需要的 JobDataMap。
    • unscheduleJob(TriggerKey triggerKey):从调度程序中删除指定的触发器。
    • unscheduleJobs(List<TriggerKey> triggerKeys):从调度程序中删除所有指示的触发器。

    4.5.4 StdSchedulerFactory

          SchedulerFactory的实现,它根据属性文件的内容完成创建 Quartz 的调度器(Scheduler) 实例的所有工作。

          默认情况下,一个名为 quartz.properties 的属性文件,属性是从“当前工作目录”加载的。如果失败,那么加载位于 org/quartz 包中的 quartz.properties 文件(作为资源)。如果希望使用这些默认值以外的文件,则必须定义系统属性 org.quartz.properties 。属性指向您想要的文件。

          或者,您可以通过在调用 getScheduler() 之前调用 initialize(xx) 方法来显式地初始化工厂。

          有关文件中可用的各种设置的信息,请参阅与Quartz一起发布的示例属性文件。完整的配置文档可以在 http://www.quartz-scheduler.org/docs/configuration/index.html 找到。

          指定的 JobStore、ThreadPool 和其他 SPI 类的实例将按名称创建,然后在配置文件中为它们指定的任何附加属性将通过调用等效的“set”方法在实例上设置。例如,如果属性文件包含属性 org.quartz.jobStore.myProp = 10。然后在 JobStore 类实例化之后,setMyProp() 方法将被调用。在调用属性的 setter 方法之前,将类型转换为基本Java类型(int、long、float、double、boolean和String)。

          一个属性可以通过指定一个遵循 $@other.property.name 约定的值来引用另一个属性的值,例如,要将调度器的实例名引用为其他属性的值,可以使用 $@org.quartz.scheduler.instanceName

    • StdSchedulerFactory():创建一个未初始化的 StdSchedulerFactory。
    • StdSchedulerFactory(Properties props):创建通过 initialize(Properties) 初始化的 StdSchedulerFactory。
    • StdSchedulerFactory(String fileName):创建通过 initialize(fileName) 初始化的 StdSchedulerFactory。
    • getAllSchedulers():返回所有已知调度器(由任何 StdSchedulerFactory 实例生成)。
    • getDefaultScheduler():返回默认调度器,如果它还不存在,则创建它。
    • getScheduler():返回此工厂生成的调度器。
    • getScheduler(String schedName):返回具有给定名称的调度器(如果它存在(如果它已经被实例化))。
    • initialize():使用 Properties 文件的内容和覆盖系统属性初始化ScheduerFactory。
    • initialize(InputStream propertiesStream):使用用给定属性文件的 InputStream 初始化SchedulerFactory。
    • initialize(Properties props):使用给定 Properties 对象的内容初始化ScheduerFactory。
    • initialize(String filename):使用给定名称的 Properties 文件的内容初始化 SchedulerFactory。

    4.5.5 JobDetail

          传递给定 Job 实例的详细属性。JobDetails将使用JobBuilder创建/定义。

          Quartz 并不存储 Job 类的实际实例,而是允许您通过使用 JobDetail 来定义 Job 类的实例。

           Job 具有与其关联的名称和组,这些名称和组应该在单个调度器中惟一地标识它们。

          触发器(Trigger)是调度 Job 的“机制”。许多 Trigger 可以指向同一 Job,但单个Trigger只能指向一个 Job。

    • getDescription():返回由其创建者(如果有的话)提供给 Job 实例的描述。
    • getJobBuilder():获得一个配置为生成与此 JobDetail 相同的 JobBuilder。
    • getJobClass():获取将要执行的作业的实例。
    • getJobDataMap():获取与作业关联的 JobDataMap。
    • getKey():返回 JobKey。
    • isConcurrentExectionDisallowed():是否禁止同时执行。
    • isDurable():Job 孤立后是否应该继续存储(没有 Trigger 指向它)。
    • isPersistJobDataAfterExecution():执行后是否保存 Job 数据。
    • requestsRecovery():指示调度器(Scheduler),如果遇到“recovery恢复”或“fail-over故障转移”情况,是否应重新执行 Job。

    上面的方法,JobDetail 接口实现类 JobDetailImpl 都有之对应的 setter 方法。

    4.5.6 JobBuilder

          JobBuilder 用于实例化 JobDetails。

          构建器将始终保持自身处于有效状态,并为随时调用 build() 设置合理的缺省值。例如,如果您没有调用 withIdentity(..),将为您生成一个作业名。

    • newJob():创建用于定义 JobDetail 的 JobBuilder。
    • ofType(Class<? extends Job> jobClazz):设置将在触发器触发与此 JobDetail 关联时实例化并执行的类。
    • newJob(Class<? extends Job> jobClass):创建用于定义 JobDetail 的 JobBuilder,并设置要执行的作业的类名。是 newJob() 和 ofType() 方法的合成。
    • build():生成此 JobBuilder 定义的 JobDetail 实例。
    • requestRecovery():指示调度器,如果遇到“恢复”或“故障转移”情况,应重新执行 Job。
    • requestRecovery(boolean jobShouldRecover):指示调度器,如果遇到“恢复”或“故障转移”情况,是否应重新执行 Job。true -> 重新执行,false -> 不重新执行。
    • storeDurably():作业孤立后应该继续存储(没有触发器指向它)。
    • storeDurably(boolean jobDurability):作业孤立后应该继续存储(没有触发器指向它)。true -> 继续存储,false -> 不继续存储。
    • usingJobData:设置 JobDetail 的 JobDataMap
    • withDescription(String jobDescription):设置作业的给定(有意义的)描述。
    • withIdentity(JobKey jobKey):使用 JobKey 来标识 JobDetail。
    展开全文
  • java定时任务Quartz整理

    千次阅读 2020-10-11 17:43:23
    quartz是一种基于java实现的任务调度框架,可以定时自动的执行你想要执行的任何任务quartz官网:http://www.quartz-scheduler.org/ Quartz的组成 任务Job(你要做什么事?) job就是你想要实现的任务类,每...

    目录

    一、Quartz介绍

    二、Quartz的组成

    三、使用java实现一个简单的Quartz例子

    四、使用Springboot整合Quartz定时任务框架

    五、使用Springboot+mybatis整合Quartz定时任务框架实现定时向数据库插入一条数据

    六、总结

    七、参考资料


    一、Quartz介绍

    quartz是一种基于java实现的任务调度框架,可以定时自动的执行你想要执行的任何任务。

    quartz官网:http://www.quartz-scheduler.org/

     

    二、Quartz的组成

    任务Job(你要做什么事?)

    job就是你想要实现的任务类,每一个job必须实现org.quartz.job接口。

    触发器Trigger(你什么时候去做?)

    Trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。

    调度器Scheduler(你什么时候需要做什么事?)

    Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job。

     

     

    三、使用java实现一个简单的Quartz例子

    1、新建一个maven项目,并引入Quartz依赖    https://mvnrepository.com/search?q=quartz

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>Quartz</artifactId>
        <version>1.0-SNAPSHOT</version>
        <dependencies>
            <!--核心包-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.2</version>
            </dependency>
            <!--工具-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>2.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.7</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    
    
    </project>

     

    2、编写一个Job类,用来编写定时任务要做什么

    package quartz.job;
    
    import javafx.scene.chart.PieChart;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class HelloJob implements Job {
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //输出当前时间
            Date date=new Date();
            SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString=dateFormat.format(date);
            //工作内容
            System.out.println("执行定时任务,时间是:"+dateString);
        }
    }
    

     

    3、编写触发器和调度器

    package quartz.job;
    
    import org.quartz.*;
    
    import org.quartz.impl.StdSchedulerFactory;
    
    public class HelloSchedulerDemo {
        public static void main(String[] args) throws Exception{
            //1、调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)
            Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();
            //2、任务实例(JobDetail)
            JobDetail jobDetail= JobBuilder.newJob(HelloJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
                    .withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称
                   .build();
            //3、触发器(Trigger)
            Trigger trigger= TriggerBuilder.newTrigger()
                    .withIdentity("trigger1","group1") //参数1:触发器的名称(唯一实例);参数2:触发器组的名称
                    .startNow() //马上启动触发器
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) //每5秒执行一次
                    .build();
            //让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
            scheduler.scheduleJob(jobDetail,trigger);
            //启动
            scheduler.start();
        }
    }
    

     

    执行结果:

     

     

    四、使用Springboot整合Quartz定时任务框架

    1、pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.springboot</groupId>
        <artifactId>Quartz</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>erp</name>
        <description>Quartz for Spring Boot</description>
    
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--导入html依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!--核心包-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.2</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--工具-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>2.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.7</version>
               <!-- <scope>compile</scope>-->
            </dependency>
            <!--添加Scheduled坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
            </dependency>
            <!--Spring tx 坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
            </dependency>
        </dependencies>
    </project>

     

    2、 job类

    package quartz.job;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.util.Date;
    
    public class QuartzDemo implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("Execute..."+new Date());
        }
    }
    

    3、配置类,配置触发器与任务调度器

    package quartz.job;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.quartz.JobDetailFactoryBean;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
    
    /**
     * Quartz配置类
     */
    @Configuration
    public class QuartzConfig {
        /**
         * 1、创建Job对象
         */
        @Bean
        public JobDetailFactoryBean jobDetailFactoryBean(){
            JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();
            //关联我们自己的Job类
            factoryBean.setJobClass(QuartzDemo.class);
            return factoryBean;
        }
    
        /**
         * 2、创建Trigger对象
         */
        @Bean
        public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
            SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();
            //关联JobDetail对象
            factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
            //该参数表示一个执行的毫秒数
            factoryBean.setRepeatInterval(2000); //每隔2秒执行一次
            //重复次数
            factoryBean.setRepeatCount(5);
            return factoryBean;
        }
    
        /**
         * 3、创建Scheduler
         */
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
            SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
            //关联trigger
            factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
            return factoryBean;
        }
    }
    

     

    4、启动类

    package quartz.job;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @EnableScheduling
    public class QuartzApplication extends SpringBootServletInitializer {
        public static void main(String[] args) {
            SpringApplication.run(QuartzApplication.class, args);
        }
    }
    

     

    执行结果:

    每隔2秒执行一次执行5次

     

    五、使用Springboot+mybatis整合Quartz定时任务框架实现定时向数据库插入一条数据

     

    IDEA项目目录结构

     

     pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.springboot</groupId>
        <artifactId>Quartz</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>erp</name>
        <description>Quartz for Spring Boot</description>
    
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--导入html依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!--核心包-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.2</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--工具-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>2.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.7</version>
               <!-- <scope>compile</scope>-->
            </dependency>
            <!--添加Scheduled坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
            </dependency>
            <!--Spring tx 坐标-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.1</version>
            </dependency>
        </dependencies>
    </project>

    application.yml

    server:
      port: 8080
    spring:
      datasource:
        name: mydb
        url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Hongkong
        username: root
        password: 123456
        driver-class-name: com.mysql.cj.jdbc.Driver
    mybatis:
      mapper-locations: classpath:Mapper/*.xml #注意:一定要对应mapper映射xml文件的所在路径
      type-aliases-package: com.springboot.quartz.Entity # 注意:对应实体类的路径
    

     

    QuartzDemoMapper类
    package com.springboot.quartz.Mapper;
    
    import com.springboot.quartz.Entity.QuartzDemo;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.springframework.stereotype.Component;
    
    @Mapper
    @Component
    public interface QuartzDemoMapper {
        @Insert("insert into QuartzDemo (op_time,operation) values (#{op_time},#{operation})")
        void insertQuartzDemo(java.sql.Timestamp op_time,String operation);
    
        @Insert("insert into QuartzDemo_1 (operation) values (#{operation})")
        void insertQuartzDemo_1(String operation);
    
       /* // @Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中
        QuartzDemo insertQuartzDemo(@Param("o_ptime") java.sql.Timestamp op_time, @Param("operation") String operation);*/
    }
    

     

    QuartzDemoService类
    package com.springboot.quartz.Service;
    
    import com.springboot.quartz.Mapper.QuartzDemoMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class QuartzDemoService {
        @Autowired
        private QuartzDemoMapper quartzDemoMapper;
    
        public void insertQuartzDemo(java.sql.Timestamp op_time,String operation){
            quartzDemoMapper.insertQuartzDemo(op_time,operation);
        }
    
        public void insertQuartzDemo_1(String operation){
            quartzDemoMapper.insertQuartzDemo_1(operation);
        }
    }
    

    Job类

    package com.springboot.quartz.job;
    
    import com.springboot.quartz.Service.QuartzDemoService;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @Component
    public class QuartzDemoJob implements Job {
        static int i = 0;
        @Autowired
        private QuartzDemoService quartzDemoService;
    
        public QuartzDemoJob() {
        }
    
        @Autowired   //这里不能直接注入,因为@Autowired注入是Spring的注入,要求注入对象与被注入对象都是在SpringIOC容器中存在,
        public QuartzDemoJob(QuartzDemoService quartzDemoService) {
            this.quartzDemoService = quartzDemoService;
        }
    
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            String operation = "测试" + i++;
            Date current_time = new Date();
            String strDate = dateToStr(current_time, "yyyy-MM-dd HH:mm:ss");
            java.sql.Timestamp op_time = strToSqlDate(strDate, "yyyy-MM-dd HH:mm:ss");
            quartzDemoService.insertQuartzDemo(op_time, operation);
            System.out.println(op_time + "------" + operation);
        }
    
        public static String dateToStr(java.util.Date date, String strFormat) {
            SimpleDateFormat sf = new SimpleDateFormat(strFormat);
            String str = sf.format(date);
            return str;
        }
    
        public static java.sql.Timestamp strToSqlDate(String strDate, String dateFormat) {
            SimpleDateFormat sf = new SimpleDateFormat(dateFormat);
            java.util.Date date = null;
            try {
                date = sf.parse(strDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            java.sql.Timestamp dateSQL = new java.sql.Timestamp(date.getTime());
            return dateSQL;
        }
    }
    

     编写Job类时要注意,Job类默认是通过AdaptableJobFactory类的createJobInstance通过newInstance()反射进行实例化的,因此没有经过Spring的处理。所以QuartzDemoJob默认是不在SpringIOC容器中的,因此@Autowired注解无法在QuartzDemoJob类中直接注入到SpringIOC容器中。

    注意:QuartzDemoJob类中一定要有无参构造方法,否则Job配置类中getObject()这块会报错!

    因此我们需要手动的把QuartzDemoJob类注入到SpringIOC容器中。

    编写一个类MyAdaptableJobFactory继承AdaptableJobFactory,覆盖createJobInstance()方法。

    MyAdaptableJobFactory类

    package com.springboot.quartz.Config;
    
    import org.quartz.spi.TriggerFiredBundle;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.scheduling.quartz.AdaptableJobFactory;
    import org.springframework.stereotype.Component;
    
    @Component("myadaptableJobFactory")  //将该类实例化,使得可以直接用
    public class MyadaptableJobFactory extends AdaptableJobFactory {
        //AutowireCapableBeanFactory可以将一个对象添加到Spring IOC容器中,并且完成该对象注入
        @Autowired
        private AutowireCapableBeanFactory autowireCapableBeanFactory;
    
        //该方法将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            Object object = super.createJobInstance(bundle);
            //将object对象添加到Spring IOC容器中并完成注入
            this.autowireCapableBeanFactory.autowireBean(object);
            return object;
        }
    }
    
    Quartz配置类
    package com.springboot.quartz.Config;
    
    import com.springboot.quartz.job.QuartzDemoJob;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
    import org.springframework.scheduling.quartz.JobDetailFactoryBean;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
    
    /**
     * Quartz配置类
     */
    @Configuration
    public class QuartzConfig {
        /**
         * 1、创建Job对象
         */
        @Bean
        public JobDetailFactoryBean jobDetailFactoryBean(){
            JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();
            //关联我们自己的Job类
            factoryBean.setJobClass(QuartzDemoJob.class);  //QuartzDemoJob的实例化并没有经过Spring的处理,
            // Spring的注入是要求注入的对象和被注入的对象都要在Spring的IOC容器中
            return factoryBean;
        }
    
        /**
         * 2、创建Trigger对象
         * Cron Trigger
         */
        @Bean
        public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
            CronTriggerFactoryBean factoryBean=new CronTriggerFactoryBean();
            //关联JobDetail对象
            factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
           //设置触发时间
            //factoryBean.setCronExpression("0/2 * * * * ?");  //每2秒触发一次, 分钟,小时,天,月,星期
            factoryBean.setCronExpression("0 0-59 0-22 * * ?");  //在每天0-22点期间的每1分钟触发
            return factoryBean;
        }
    
        /**
         * 3、创建Scheduler
         */
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyadaptableJobFactory myadaptableJobFactory){
            SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
            //关联trigger
            factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
            factoryBean.setJobFactory(myadaptableJobFactory);  //调用myadaptableJobFactory把对象注入到SpringIOC容器中
            return factoryBean;
        }
    }
    

     setCronExpression()方法可以设置定时器触发时间,具体设置规则可以参考下图

     图片来源:https://blog.csdn.net/fxj8291247/article/details/52329946

     

    启动类

    package com.springboot.quartz;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @EnableScheduling
    @SpringBootApplication
    /*@MapperScan("com.springboot.quartz.Mapper")*/
    public class QuartzApplication extends SpringBootServletInitializer {
        public static void main(String[] args) {
            SpringApplication.run(QuartzApplication.class, args);
        }
    }
    

     

    执行结果:

    写入的数据库

     

    六、总结

    quartz定时任务是由Job、Trigger和Scheduler三部分组成。Job里面写定时任务的具体做什么,Trigger设定定时任务的执行时间,Scheduler则负责整个定时任务的调度。java单一使用quartz框架比较简单。如果是Spring配置quartz则要注意Job的注入问题。因为默认Job是由AdaptableJobFactory类中的createJobInstance方法进行实例化因此不会在SpringIOC中的,所以需要覆盖AdaptableJobFactory类中的createJobInstance方法,手动将Job对象注入到SpringIOC容器中。

     

    七、参考资料

    https://www.bilibili.com/video/BV19t41127de?from=search&seid=2343824906917884403

    https://www.bilibili.com/video/BV1mE411F7NJ?p=6

    https://blog.csdn.net/fxj8291247/article/details/52329946

    https://bbs.csdn.net/topics/360004856

    https://blog.csdn.net/u012373815/article/details/86740625

    https://blog.csdn.net/womeng2009/article/details/80328544

    展开全文
  • java定时执行任务quartz定时执行任务
  • Java定时任务Quartz

    千次阅读 2018-06-02 22:58:15
    1.概要 Quartz是由OpenSymphony提供的强大的开源任务调度框架。官网地址:http://www.quartz-scheduler.org/,纯Java实现。强大的调度功能:很容易与Spring集成,提供调度运行环境的持久化机制,保存并恢复任务调度...

    1.概要

          Quartz是由OpenSymphony提供的强大的开源任务调度框架。官网地址:http://www.quartz-scheduler.org/,纯Java实现。

    • 强大的调度功能:很容易与Spring集成,提供调度运行环境的持久化机制,保存并恢复任务调度现场。即使系统因故障关闭,任务调度现场数据也不会丢失;
    • 灵活的应用方式:允许灵活的定义触发器的调度时间表,并可以对触发器和任务进行关联映射,提供了组件式的监听器、各种插件、线程池等功能,支持任务和调度的多种组合方式、支持调度数据的多种存储方式,支持分布式和集群操作;
    • 主要用到的设计模式:Builder模式、Factory模式、组件模式、链式写法;
    • 核心概念:调度器——负责定期、定时、定频率的去执行任务;任务——具体的业务逻辑;触发器——调度器调度任务的时间;
    • 重要组成:Job——接口且可以接收参数;JobDetail——Job的实现类和相关的静态信息;JobBuilder——定义或者创建JobDetail的实例;JobStore——用来保存Job数据;Trigger——描述触发Job执行时的时间触发规则;TriggerBuilder——定义或者创建触发器的实例;ThreadPool——线程池Job运行的基础设施;Scheduler——Quartz独立运行的容器;Calendar——一个Trigger可以和多个Calendar关联,以排除或者包含某些时间点;监听器——JobListener、TriggerListener、SchedulerLIstener监听对应的组件。

    2.Quartz的基本使用

    1.每两秒钟打印一次Hello World:

    创建Job实现类HelloJob

    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    public class HelloJob implements Job{
    	@Override
    	public void execute(JobExecutionContext arg0) throws JobExecutionException {
    		//打印当前执行时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("任务执行时间为:"+sf.format(startTime));
    		System.out.println("Hello World");
    	}
    }

    创建Job测试类HelloScheduler

    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    public class HelloScheduler {
    	public static void main(String[] args) throws SchedulerException {
    		// 创建一个JobDetail实例与HelloJob类绑定
    		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
    		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
    		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").startNow()
    				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
    		//创建scheduler实例
    		SchedulerFactory sFactory = new StdSchedulerFactory();
    		Scheduler scheduler = sFactory.getScheduler();
    		scheduler.start();
    		//打印当前时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("打印当前时间:"+sf.format(startTime));
    		scheduler.scheduleJob(jobDetail,trigger);
    	}
    }
    2.浅谈Job&JobDetail

         Job:实现业务逻辑的任务接口,job接口非常容易实现,只有一个execute方法,类似TimerTask的run方法,在里面编写业务逻辑。Job在Quartz中的生命周期:每次调度器执行Job时,它在调用execute方法前会创建一个新Job实例;当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。JobDetail为job提供了很多设置属性name、group、jobClass、jobDataMap(用来存储特定Job实例的状态信息),调度器需要借助JobDetail对象来添加Job实例。

    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    public class HelloScheduler {
    	public static void main(String[] args) throws SchedulerException {
    		// 创建一个JobDetail实例与HelloJob类绑定
    		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
    		System.out.println("JobDetail's name:"+jobDetail.getKey().getName());
    		System.out.println("JobDetail's group:"+jobDetail.getKey().getGroup());
    		System.out.println("JobDetail's jobClass:"+jobDetail.getJobClass().getName());
    		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
    		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").startNow()
    				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
    		//创建scheduler实例
    		SchedulerFactory sFactory = new StdSchedulerFactory();
    		Scheduler scheduler = sFactory.getScheduler();
    		scheduler.start();
    		//打印当前时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("打印当前时间:"+sf.format(startTime));
    		scheduler.scheduleJob(jobDetail,trigger);
    	}
    }
    3.浅谈JobExecutionContext&JobDataMap

          当Schedule调用一个Job,就会将JobExecutionContext传递给Job的execute方法;Job能通过JobExecutionContext对象访问到Quartz运行时的环境以及Job本身的明细数据。在进行任务调度时,JobDataMap存储在JobExecutionContext中,非常方便获取;JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它;JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型。获取JobDataMap的两种方式:

    • 从Map中直接获取,示例代码如下Job:
    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.JobKey;
    import org.quartz.TriggerKey;
    public class HelloJob implements Job{
    	@Override
    	public void execute(JobExecutionContext context) throws JobExecutionException {
    		//打印当前执行时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("任务执行时间为:"+sf.format(startTime));
    		JobKey key = context.getJobDetail().getKey();
    		System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
    		TriggerKey triggerKey = context.getTrigger().getKey();
    		System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
    		JobDataMap jobMap = context.getJobDetail().getJobDataMap();
    		JobDataMap triggerMap = context.getTrigger().getJobDataMap();
    //		JobDataMap dataMap = context.getMergedJobDataMap(); //获取合并处理后的参数集合
    		String jobMsg = jobMap.getString("message");
    		Float floatValue = jobMap.getFloat("float");
    		String triggerMsg = triggerMap.getString("triggerMsg");
    		Double doubleValue = triggerMap.getDouble("double");
    		System.out.println("My job params are:"+jobMsg+":"+floatValue);
    		System.out.println("My trigger params are:"+triggerMsg+":"+doubleValue);
    	}
    }

    示例代码Schedule:

    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    public class HelloScheduler {
    	public static void main(String[] args) throws SchedulerException {
    		// 创建一个JobDetail实例与HelloJob类绑定
    		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").
    				usingJobData("message", "Hello MyJob1").usingJobData("float", 3.14F).build();
    		
    		//如果传递参数过程中key相同,则trigger的参数值会覆盖jobdetail里面的参数值
    		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
    		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").
    				usingJobData("triggerMsg", "Hello MyTrigger1").usingJobData("double", 2.0D).
    				startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().
    						withIntervalInSeconds(2).repeatForever()).build();
    		//创建scheduler实例
    		SchedulerFactory sFactory = new StdSchedulerFactory();
    		Scheduler scheduler = sFactory.getScheduler();
    		scheduler.start();
    		//打印当前时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("打印当前时间:"+sf.format(startTime));
    		scheduler.scheduleJob(jobDetail,trigger);
    	}
    }
    • Job实现类中添加setter方法对应JobDataMap的键值(Quartz框架默认的JobFactory实现类在初始化Job实例对象时会自动地调用这些setter方法),如下代码所示Job:
    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.JobKey;
    import org.quartz.TriggerKey;
    public class HelloJob implements Job{
    	private String message;
    	private Float floatValue;
    	private Double doubleValue;
    	
    	public String getMessage() {
    		return message;
    	}
    	public void setMessage(String message) {
    		this.message = message;
    	}
    	public Float getFloatValue() {
    		return floatValue;
    	}
    	public void setFloatValue(Float floatValue) {
    		this.floatValue = floatValue;
    	}
    	public Double getDoubleValue() {
    		return doubleValue;
    	}
    	public void setDoubleValue(Double doubleValue) {
    		this.doubleValue = doubleValue;
    	}
    	@Override
    	public void execute(JobExecutionContext context) throws JobExecutionException {
    		//打印当前执行时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("任务执行时间为:"+sf.format(startTime));
    		JobKey key = context.getJobDetail().getKey();
    		System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
    		TriggerKey triggerKey = context.getTrigger().getKey();
    		System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
    		System.out.println("Message is:"+message);
    		System.out.println("Float is:"+floatValue);
    		System.out.println("Double is:"+doubleValue);
    	}
    }
    

    示例代码Schedule:

    package com.luna.timer.quarts;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    public class HelloScheduler {
    	public static void main(String[] args) throws SchedulerException {
    		// 创建一个JobDetail实例与HelloJob类绑定
    		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").
    				usingJobData("message", "Hello MyJob1").usingJobData("floatValue", 3.14F).build();
    		
    		//如果传递参数过程中key相同,则trigger的参数值会覆盖jobdetail里面的参数值
    		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
    		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").
    				usingJobData("triggerMsg", "Hello MyTrigger1").usingJobData("doubleValue", 2.0D).
    				startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().
    						withIntervalInSeconds(2).repeatForever()).build();
    		//创建scheduler实例
    		SchedulerFactory sFactory = new StdSchedulerFactory();
    		Scheduler scheduler = sFactory.getScheduler();
    		scheduler.start();
    		//打印当前时间
    		Date startTime = new Date();
    		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		System.out.println("打印当前时间:"+sf.format(startTime));
    		scheduler.scheduleJob(jobDetail,trigger);
    	}
    }
    展开全文
  • java 定时任务 quartz

    2010-09-07 09:47:09
    定时任务:自运行时,每隔一段时间执行一次。使用quartz来做定时任务,简单。   在java中的使用,实例: quartz.rar     定时任务在spring中的集成: 需要加入spring-context-support.jar, spring-tx.jar,...

    定时任务:自运行时,每隔一段时间执行一次。使用quartz来做定时任务,简单。

     

    在java中的使用,实例: quartz.rar

     

     

    定时任务在spring中的集成:

    需要加入spring-context-support.jar, spring-tx.jar,  commons-collections.jar

     

    实例:quartz-spring.rar

     

    注意:在spring中配置了以后,定时任务自动启动

    展开全文
  • Java对于Quartz的理解和使用,并提供quartz的工具类供大家参考和使用
  • Java定时任务Quartz

    千次阅读 2018-06-03 15:21:48
    1.浅谈Trigger2.浅谈CronTrigger3.Quartz实际应用4.总结
  • java使用quartz定时执行任务

    千次阅读 2019-03-30 14:47:52
    项目中需要有一个定时任务,在每年一月一日查询人员表中的信息,根据身份证号码,修改用户年龄。项目使用架构为Spring,Spring ...-- 定时任务quartz需要依赖的jar--> <dependency> <groupId>org....
  • java quartz 定时任务

    2018-06-01 13:54:34
    使用quartz实现的java 定时任务,通过写cron表达式,让任务在制定时刻触发执行
  • Java定时任务Quartz

    2017-09-22 15:09:21
    前言Java小白一个,最近查看项目中关于定时器的源码,尝试自己配置了一下。文件参考jar包这是在定时器实现中使用到的jar包 c3p0-0.9.1.1.jar jta.jar log4j-1.2.16.jar quartz-2.2.2.jar quartz-jobs-2.2.2.jar slf4...
  • 如果选择定时任务,那么Quartz是一个不错的框架,但是在使用的过程中,莫名发现Quartz定时任务在指定时间被执行了两次。 问题原因 在Tomcat的配置文件conf/server.xml中: &amp;amp;lt;Host name=&amp;...
  • quartz定时任务不执行

    千次阅读 2020-02-26 13:54:27
    quartz定时任务执行一段时间不执行的原因 数据库表QRTZ_TRIGGERS 里的TRIGGER_STATE 字段的值自动修改为ERROR了 ,quartz定时任务扫描这种ERROR情况. 之所以出现ERROR 原因在于job里有bug,导致quartz自动将状态...
  • 0 0 12 * * ? 每天12点运行 0 15 10 ? * * 每天10:15运行 0 15 10 * * ? 每天10:15运行 0 15 10 * * ? * 每天10:15运行 0 15 10 * * ? 2008 在2008年的每天10:15运行 0 * 14 * * ? 每天14点到15点之间每分钟运行一...
  • Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。 Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。 它提供...
  • Java Web实现定时任务quartz方式

    千次阅读 2017-11-20 18:59:27
    Quartz是一个完全由java编写的开源作业调度框架,具体的介绍可到http://www.opensymphony.com/quartz/官方网站查看。 Quartz的几个核心的接口和类为: Job接口:自己写的“定时程序”实现此接口的void execute...
  • quartz定时任务突然不执行

    千次阅读 2020-03-27 18:52:07
    高并发情况下,quartz定时任务突然不执行了, 背景: 整个项目架构,高并发操作比较多, 有多个线程池,周期线程池,和定时任务,占用多个资源 导致现场出现定时任务走一段时间就走的情况 当前定时任务配置的是单...
  • quartz 动态定时任务 根据数据库数据配置动态定时任务
  • Java定时任务Timer和Quartz

    千次阅读 2018-09-12 10:13:23
    定时任务调度 ... 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务 定时任务工具 Timer Quartz ... Timer能完成一些简单的定时任务,能实现...只有一个后台执行定时任务Quartz能实现更复杂...
  • 什么是定时任务:基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。 在Java中的定时调度工具:Timer 和 Quartz timer和quartz的区别: timer 和 quartz相比,timer是小弟,能完成日常开发中60...
  • 在实际开发过程中难免会设置定时任务定时任务的调用方法也很多,可以通过中间层调用,也可以通过数据库调用,今天就先介绍下中间层调用的方法吧: 环境: 实现大概: 通过写个监听器开启任务,通过Cron表达式...
  • java实现定时任务(Quartz)

    千次阅读 2016-04-26 16:06:27
    java中实现定时任务执行某一业务。具体操作如下: 1、定义初始化任务 2、任务业务操作 3、定义初始化方法 4、在web.xml中注册启动 5、定义具体执行时间 6、quartz定时任务时间设置 quartz定时任务...
  • 定时任务quartzjava注解

    千次阅读 2016-10-13 14:50:10
    在现在项目中注解应用越来越广泛。为了有更深的理解,前面学习了java注解使用的一些原理,做了相关的总结和梳理,对注解有了...一般的管理系统中,都会有定时执行任务,一般用于按一定规律进行统计。比如日,周,月的
  • 想要定时运行脚本,jenkins虽然可以实现,但是用的爽,所以改成quartz试一试 灵感来自 https://tech.youzan.com/youzan-online-active-testing/ quartz官方教程 ...
  • 定时任务框架quartz、elastic-job和xxl-job分析定时任务框架quartz、elastic-job和xxl-job分析一、概述二、对比三、总结四、分析elastic-job-lite框架4.1 概述4.2 架构图4.3 作业启动流程图4.4 作业执行流程图4.5 ...
  • Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据一定的时间间隔来调度作业。我学一样东西,从来都是从实践出发,边用边学,用起来...
  • Java定时框架quartz简介

    2018-10-25 16:25:26
    我们在写Java程序中经常会写一些定时执行任务,例如每天执行一次什么方法,几分钟或者几个小时调用一次存储过程等等 Quartz的三个核心概念: 任务执行工作的内容,Quartz提供job接口来支持任务定义 触发器:定义...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,168
精华内容 6,467
关键字:

java定时任务quartz不执行

java 订阅