spring学习笔记(26)spring整合Quartz2持久化稳健任务调度

简介: <div class="markdown_views"><p>在<a href="http://blog.csdn.net/qwe6112071/article/details/50989192">《Quartz任务调度(3)存储与持久化操作配置详细解析 》</a>一文中,我们通过配置quartz.properties属性文件实现了Quartz的数据库持久化操作。现在整合sp

《Quartz任务调度(3)存储与持久化操作配置详细解析 》一文中,我们通过配置quartz.properties属性文件实现了Quartz的数据库持久化操作。现在整合spring的原理,就是相当于把我们在属性文件中的配置属性整合进SchedulerFactoryBean中,来生成我们的Scheduler类。
这里需要特别注意的是,我们通过Bean配置生成的JobDetail和CronTrigger或SimpleTrigger不能被序列化,因而不能持久化到数据库中,如果想要使用持久化任务调度,我们需要编程式创建Quartz的Job等相关实现类。下面是我们的配置实例:

spring容器配置

<bean id="quartzDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >  
   <property name="driverClassName" value="com.mysql.jdbc.Driver"/>    
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/quartz"/>    
    <property name="username" value="root"/>    
    <property name="password" value="root"/>     
</bean>  

<!-- quartz持久化存储  -->   
<bean name="quartzScheduler"  
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    <property name="dataSource">  
        <ref bean="quartzDataSource" />  
    </property>  
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />  
    <property name="quartzProperties">  
    <props>  
        <!-- JobStore 配置 -->  
        <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>  
           <!-- 数据表设置 -->  
        <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>  
        <prop key="org.quartz.jobStore.dataSource">myDatadource</prop>  
    </props>         
    </property>  
</bean>    

在连接数据前,我们需要先在数据库中创建好对应的表格,在我开始提到的文章内有相关的sql语句。此外,关于quartzProperties还有很多配置属性,如配置线程池、集群等,在我开头提到的那篇文章内都有详细说明。

测试类配置

package tool.job;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.ObjectAlreadyExistsException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class pickNewsJob implements Job {

    @Override
    public void execute(JobExecutionContext jec) throws JobExecutionException {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        System.out.println("在" + sdf.format(new Date()) + "更新日志");
    }

    public static void main(String args[]) throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(pickNewsJob.class)
                .withIdentity("job1", "jgroup1").build();
        SimpleTrigger simpleTrigger = TriggerBuilder
                .newTrigger()
                .withIdentity("trigger1")
                .withSchedule(
                        SimpleScheduleBuilder
                                .repeatSecondlyForTotalCount(10, 2)).startNow()
                .build();
        try{
            ApplicationContext ac = new ClassPathXmlApplicationContext("spring/spring-task.xml");
            Scheduler scheduler = (Scheduler) ac.getBean("quartzScheduler");
            scheduler.scheduleJob(jobDetail, simpleTrigger);
            scheduler.start();  
        }catch ( ObjectAlreadyExistsException e) {
            resumeJob();
        }
    }
    /**
     *根据数据库中的记录 恢复异常中断的任务
     */
    public static void resumeJob() throws SchedulerException {
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // ①获取调度器中所有的触发器组
        List<String> triggerGroups = scheduler.getTriggerGroupNames();
        // ②重新恢复在tgroup1组中,名为trigger1触发器的运行
        for (int i = 0; i < triggerGroups.size(); i++) {
            List<String> triggers = scheduler.getTriggerGroupNames();
            for (int j = 0; j < triggers.size(); j++) {
                Trigger tg = scheduler.getTrigger(new TriggerKey(triggers
                        .get(j), triggerGroups.get(i)));
                // ②-1:根据名称判断
                if (tg instanceof SimpleTrigger
                        && tg.getDescription().equals("jgroup1.DEFAULT")) {//由于我们之前测试没有设置触发器所在组,所以默认为DEFAULT
                    // ②-1:恢复运行
                    scheduler.resumeJob(new JobKey(triggers.get(j),
                            triggerGroups.get(i)));
                }
            }
        }
        scheduler.start();

    }
}

在这里,如果我们测试时在运行中断后再重复运行,会出现ObjectAlreadyExistsException异常,原因是我们创建的JobDetail和Trigger等的名字和数据库中已有记录冲突,新的任务尝试持久到数据库失败。在程序中,我的处理方法是先捕捉异常,然后调用恢复任务方法,来重新执行异常中断的任务。

源码下载

本例源码可到我的github仓库https://github.com/jeanhao/spring的springQuartz文件夹下载

目录
相关文章
|
1月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
8月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
299 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
5月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
668 2
|
7月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
184 20
|
Java Maven Spring
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
这篇文章介绍了在IntelliJ IDEA社区版中创建Spring Boot项目的三种方法,特别强调了第三种方法的详细步骤。
10676 0
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
274 9
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
825 2
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
833 1
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
177 9
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
114 1