quartz定时任务动态配置详细教程(附demo)(三)

来源:互联网 发布:java微信接口开发 编辑:程序博客网 时间:2024/06/16 02:54

源码地址:https://gitee.com/seek412/quartz03.git
在上一章节中介绍了spring整合quartz定时任务,但是想要修改、停止定时任务就必须重启服务器。实际需求往往更复杂,下面介绍如何在前端页面控制定时任务的启动,暂停,修改定时任务的时间等

项目结构
项目结构图

步骤1:数据库设计

在上一章介绍了spring整合quartz,下面是配置文件

<!-- class文件对应定时任务的路径,如果有多个定时任务就配置多个 -->    <bean id="quartzJobA" class="com.demo.schedule.QuartzJobA"/>    <bean id="quartzJobB" class="com.demo.schedule.QuartzJobB"/>    <bean id="jobDetailA" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">        <!-- 这里的name必须是targetObject和targetMethod -->        <property name="targetObject" ref="quartzJobA"/>        <property name="targetMethod" value="jobA"/>    </bean>    <bean id="jobDetailB" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">        <property name="targetObject" ref="quartzJobB"/>        <property name="targetMethod" value="jobB"/>    </bean>    <!-- 定义触发的条件 -->    <bean id="jobTriggerA" class="org.springframework.scheduling.quartz.CronTriggerBean">        <!-- 这里的name必须是jobDetail和cronExpression -->        <property name="jobDetail" ref="jobDetailA"/>        <!-- 每隔5秒执行一次 -->        <property name="cronExpression" value="0/5 * * * * ?"/>    </bean>    <bean id="jobTriggerB" class="org.springframework.scheduling.quartz.CronTriggerBean">        <property name="jobDetail" ref="jobDetailB"/>        <property name="cronExpression" value="0/5 * * * * ?"/>    </bean>    <!-- 总管理类,如果将lazy-init='false',那么容器启动就会执行调度程序 -->    <bean id="startQuartz" lazy-init="false" autowire="no"          class="org.springframework.scheduling.quartz.SchedulerFactoryBean">        <property name="triggers">            <list>                <ref bean="jobTriggerA"/>                <ref bean="jobTriggerB"/>            </list>        </property>    </bean>

从上面的配置文件中我们可以看到,有如下字段需要我们指定:

bean id
bean class:需要执行的定时任务的路径
targetMethod:需要执行的定时任务的方法
Expression:定时任务执行频率

设计数据库字段如下:

    CREATE TABLE `schedule_job` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',  `job_name` varchar(255) DEFAULT NULL COMMENT '任务名',  `job_group` varchar(255) DEFAULT NULL COMMENT '任务组',  `method_name` varchar(255) DEFAULT NULL COMMENT '要执行的方法',  `bean_class` varchar(255) DEFAULT NULL COMMENT '定时任务所在的类路径',  `status` int(11) DEFAULT NULL COMMENT '任务状态  0:正常  1:暂停',  `cron_expression` varchar(255) DEFAULT NULL COMMENT '时间表达式',  `params` varchar(255) DEFAULT NULL COMMENT '参数',  `remark` varchar(255) DEFAULT NULL COMMENT '备注',  `create_time` datetime DEFAULT NULL COMMENT '创建时间',  `modify_time` datetime DEFAULT NULL COMMENT '修改时间',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

步骤2:搭建ssm开发环境

2.1 引入依赖包

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.demo</groupId>    <artifactId>quartz03</artifactId>    <packaging>war</packaging>    <version>1.0-SNAPSHOT</version>    <name>quartz03 Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>        <!-- 引入项目依赖的jar包 -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-webmvc</artifactId>            <version>4.3.7.RELEASE</version>        </dependency>        <!-- spring jdbc-->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-jdbc</artifactId>            <version>4.3.7.RELEASE</version>        </dependency>        <!-- spring面向切面编程 -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-aspects</artifactId>            <version>4.3.7.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context-support</artifactId>            <version>4.3.7.RELEASE</version>        </dependency>        <!-- mybatis -->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.4.2</version>        </dependency>        <!-- mybatis与spring整合包 -->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis-spring</artifactId>            <version>1.3.1</version>        </dependency>        <!-- mybatis逆向工程-->        <dependency>            <groupId>org.mybatis.generator</groupId>            <artifactId>mybatis-generator-core</artifactId>            <version>1.3.5</version>        </dependency>        <!-- pageHelper分页插件-->        <dependency>            <groupId>com.github.pagehelper</groupId>            <artifactId>pagehelper</artifactId>            <version>5.0.0</version>        </dependency>        <!-- 数据库连接池druid-->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>1.0.18</version>        </dependency>        <!-- 数据库驱动包-->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.40</version>        </dependency>        <!--servlet相关-->        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>jstl</artifactId>            <version>1.2</version>        </dependency>        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>javax.servlet-api</artifactId>            <version>3.0.1</version>        </dependency>        <!-- 引入org.apache.commons.lang包-->        <dependency>            <groupId>commons-lang</groupId>            <artifactId>commons-lang</artifactId>            <version>2.6</version>        </dependency>        <!-- quartz作业调度-->        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz</artifactId>            <version>2.3.0</version>        </dependency>        <!-- json解析 -->        <dependency>            <groupId>org.codehaus.jackson</groupId>            <artifactId>jackson-mapper-asl</artifactId>            <version>1.9.13</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-databind</artifactId>            <version>2.7.4</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-core</artifactId>            <version>2.7.4</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-annotations</artifactId>            <version>2.7.4</version>        </dependency>    </dependencies>    <build>        <finalName>quartz03</finalName>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <configuration>                    <source>1.7</source>                    <target>1.7</target>                    <encoding>UTF-8</encoding>                </configuration>            </plugin>        </plugins>        <resources>            <resource>                <directory>src/main/java</directory>                <includes>                    <include>**/*.xml</include>                </includes>            </resource>        </resources>    </build></project>

2.2 添加配置文件

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns="http://www.springframework.org/schema/beans"       xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    http://www.springframework.org/schema/aop    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd    http://www.springframework.org/schema/tx    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd    http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.1.xsd">    <!-- 1. 配置数据库配置文件 -->    <bean id = "property" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">        <property name="locations">            <list>                <value>classpath:database.properties</value>            </list>        </property>    </bean>    <!-- 2. 使用druid连接数据库 -->    <bean id = "dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method = "close">        <!-- 数据库基本信息配置 -->        <property name = "url" value = "${url}" />        <property name = "username" value = "${username}" />        <property name = "password" value = "${password}" />        <property name = "driverClassName" value = "${driverClassName}" />        <property name = "filters" value = "${filters}" />        <!-- 最大并发连接数 -->        <property name = "maxActive" value = "${maxActive}" />        <!-- 初始化连接数量 -->        <property name = "initialSize" value = "${initialSize}" />        <!-- 配置获取连接等待超时的时间 -->        <property name = "maxWait" value = "${maxWait}" />        <!-- 最小空闲连接数 -->        <property name = "minIdle" value = "${minIdle}" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name = "timeBetweenEvictionRunsMillis" value ="${timeBetweenEvictionRunsMillis}" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name = "minEvictableIdleTimeMillis" value ="${minEvictableIdleTimeMillis}" />        <!-- 用来检测连接是否有效sql,要求是一个查询语句 -->        <property name = "validationQuery" value = "${validationQuery}" />        <!-- 建议配置为true,不影响性能,并且保证安全性 -->        <property name = "testWhileIdle" value = "${testWhileIdle}" />        <!-- 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->        <property name = "testOnBorrow" value = "${testOnBorrow}" />        <!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->        <property name = "testOnReturn" value = "${testOnReturn}" />        <!-- 要启用PSCache,必须配置大于0 -->        <property name = "maxOpenPreparedStatements" value ="${maxOpenPreparedStatements}" />        <!-- 打开 removeAbandoned 功能 -->        <property name = "removeAbandoned" value = "${removeAbandoned}" />        <!-- 1800 秒,也就是 30 分钟 -->        <property name = "removeAbandonedTimeout" value ="${removeAbandonedTimeout}" />        <!-- 关闭 abanded 连接时输出错误日志 -->        <property name = "logAbandoned" value = "${logAbandoned}" />    </bean>    <!-- 3. 启用自动扫描 -->    <context:component-scan base-package="com.demo.*">        <!-- 排除注解为controller的类型 -->        <context:exclude-filter type="annotation"  expression="org.springframework.stereotype.Controller" />    </context:component-scan>    <!-- 4. 配置和mybatis的整合 -->    <bean id = "sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">        <!-- 指定mybatis的全局文件位置 -->        <property name="configLocation" value="classpath:mybatis.xml"/>        <property name="dataSource" ref="dataSource"/>        <!-- 指定mybatis的mapper文件 -->        <property name="mapperLocations">            <list>                <value>classpath:/mapper/*.xml</value>            </list>        </property>    </bean>    <!-- 5. 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <!-- 扫描所有dao接口的实现,加入到 ioc容器中 -->        <property name="basePackage" value="com.demo.dao"/>    </bean>    <!-- 6. 事务控制 -->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <!-- 控制住数据源 -->        <property name="dataSource" ref="dataSource" />    </bean>    <!-- 7. 开启基于注解的事务,使用xml配置形式的事务 -->    <aop:config>        <!-- 切入点表达式 -->        <aop:pointcut expression="execution(* com.demo.service..*(..))" id="txPoint"/>        <!-- 配置事务增强 -->        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>    </aop:config>    <!--  8. 配置事务增强,也就是事务如何切入 -->    <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <!-- 所有的方法都是事务方法 -->            <tx:method name="*"/>            <!-- 以get开始的所有方法 -->            <tx:method name="get*" read-only="true"/>        </tx:attributes>    </tx:advice>    <bean id = "springContextUtils" class="com.demo.common.utils.SpringContextUtils"/>     <!--9. Quartz定时任务动态配置 -->    <bean id = "schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/></beans>

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xmlns="http://www.springframework.org/schema/beans"       xsi:schemaLocation="    http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.1.xsd    http://www.springframework.org/schema/mvc    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">    <!-- 1. 注解探测器 -->    <context:component-scan base-package="com.demo.controller">    </context:component-scan>    <!-- 2. 配置视图解析器,方便页面返回-->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/page/"/>        <property name="suffix" value=".jsp"/>    </bean>    <!-- 3.两个标准配置 -->    <mvc:default-servlet-handler/>    <mvc:annotation-driven/>    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">        <property name="messageConverters">            <list>                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>            </list>        </property>    </bean></beans>

mybatis.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!-- 1. 驼峰规则命名 -->    <settings>        <setting name="mapUnderscoreToCamelCase" value="true"/>    </settings>    <!-- 2. 别名 -->    <typeAliases>        <typeAlias type="com.demo.domain.ScheduleJob" alias="ScheduleJob"/>    </typeAliases>    <!-- 3. 引入分页插件 -->    <plugins>        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>    </plugins></configuration>

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"         xmlns="http://java.sun.com/xml/ns/javaee"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  <display-name>Archetype Created Web Application</display-name>    <!-- 1. 启动spring容器 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:applicationContext.xml</param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- 2. springmvc前端控制器,拦截所有请求 -->    <servlet>        <servlet-name>springmvc</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:spring-mvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>springmvc</servlet-name>        <url-pattern>*.action</url-pattern>    </servlet-mapping>    <servlet-mapping>        <servlet-name>springmvc</servlet-name>        <url-pattern>*.do</url-pattern>    </servlet-mapping>    <servlet-mapping>        <servlet-name>springmvc</servlet-name>        <url-pattern>*.json</url-pattern>    </servlet-mapping>    <!-- 3. 字符编码过滤器配置 ,字符过滤器要放在所有过滤器的前面-->    <filter>        <filter-name>characterEncodingFilter</filter-name>        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>        <init-param>            <param-name>forceRequestEncoding</param-name>            <param-value>true</param-value>        </init-param>        <init-param>            <param-name>forceResponseEncoding</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>characterEncodingFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- 5. 连接池启用Web监控统计功能start-->    <filter>        <filter-name>DruidWebStatFilter</filter-name>        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>        <init-param>            <param-name>exclusions</param-name>            <param-value>*. js ,*. gif ,*. jpg ,*. png ,*. css ,*. ico ,/ druid /*</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>DruidWebStatFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <servlet>        <servlet-name>DruidStatView</servlet-name>        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>DruidStatView</servlet-name>        <url-pattern>/druid/*</url-pattern>    </servlet-mapping>    <!-- 连接池启用Web监控统计功能end--></web-app>

database.properties

#druid配置url:jdbc\:mysql\://localhost\:3306/quartz03?characterEncoding\=utf8&allowMultiQueries\=truedriverClassName:com.mysql.jdbc.Driverusername:rootpassword:adminfilters:statmaxActive:20initialSize:1maxWait:60000minIdle:10maxIdle:15timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:SELECT 'x'testWhileIdle:truetestOnBorrow:falsetestOnReturn:falsemaxOpenPreparedStatements:20removeAbandoned:trueremoveAbandonedTimeout:1800logAbandoned:true

步骤3:前端页面

前端页面表格使用的bootstrap table,这里不再累述,页面样式如下:
index.jsp

<%--  Created by IntelliJ IDEA.  User: Administrator  Date: 2017/11/25 0020  Time: 下午 18:28  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="fn"  uri="http://java.sun.com/jsp/jstl/functions" %><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><c:set var="basePath" value="${pageContext.request.contextPath}" /><!DOCTYPE html><html><head>    <title>定时任务</title>    <link rel="stylesheet" href="${basePath}/static/bootstrap-dist/css/bootstrap.min.css">    <link rel="stylesheet" href="${basePath}/static/font-awesome/css/font-awesome.min.css">    <link rel="stylesheet" href="${basePath}/static/css/bootstrap-table.min.css">    <script src="${basePath}/static/js/jquery-2.0.3.min.js"></script>    <script src="${basePath}/static/bootstrap-dist/js/bootstrap.min.js"></script>    <script src="${basePath}/static/js/bootstrap-table.min.js"></script>    <script src="${basePath}/static/js/bootstrap-table-zh-CN.js"></script></head><body><div id="rrapp" style="margin: 100px;">    <div id="showList">        <div class="grid-btn" style="height:34px;">            <a class="btn btn-primary" onclick="update();"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</a>            <a class="btn btn-primary" onclick="pause();"><i class="fa fa-pause"></i>&nbsp;暂停</a>            <a class="btn btn-primary" onclick="resume();"><i class="fa fa-play"></i>&nbsp;恢复</a>            <a class="btn btn-primary" onclick="runOnce();"><i class="fa fa-arrow-circle-right"></i>&nbsp;立即执行</a>        </div>        <table id="table"></table>    </div>    <!-- 修改时间模态框 -->    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">        <div class="modal-dialog" role="document">            <div class="modal-content">                <div class="modal-header">                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">                        <span aria-hidden="true">&times;</span>                    </button>                    <h4 class="modal-title" id="myModalLabel">修改定时任务时间</h4>                </div>                <div class="modal-body">                    <input type="text" id="modalId" style="display:none"/>                    Cron表达式                    <input type="text" class="form-control" id="modalCron">                </div>                <div class="modal-footer">                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>                    <button type="button" class="btn btn-primary" onclick="updateCron();">Save changes</button>                </div>            </div>        </div>    </div></div><script type="text/javascript">    $(function () {        //初始化表格        initTable();    });    //修改按钮    function update() {        //获取选中的行        var a = $("#table").bootstrapTable('getSelections');        if (a.length == 0) {            alert("请先选中需要修改的项");            return false;        } else if (a.length > 1) {            alert("只能选择一项");            return false;        }        $("#modalId").val(a[0].id);        $('#myModal').modal('toggle');    }    //更新定时任务时间    function updateCron() {        $('#myModal').modal('hide');        var id = $("#modalId").val();        var queryUrl = "${basePath}/scheduleJob/updateCron.do";        $.ajax({            type: 'POST',            data: {                id: id,                cronExpression: $("#modalCron").val(),            },            url: queryUrl,            success: function (result) {                //刷新表格                var opt = {                    url: '${basePath}/scheduleJob/listAllJob.do'                };                $("#table").bootstrapTable('refresh', opt);            }        })    }    //暂停一个定时任务    function pause() {        var queryUrl = '${basePath}/scheduleJob/pauseJob.do';        commonSubmit(queryUrl);    }    //恢复一个定时任务    function resume() {        var queryUrl = '${basePath}/scheduleJob/resumeJob.do';        commonSubmit(queryUrl);    }    //立即执行一个定时任务    function runOnce() {        var queryUrl = "${basePath}/scheduleJob/runOnce.do";        commonSubmit(queryUrl);    }    //暂停、恢复、立即执行提交函数    function commonSubmit(queryUrl) {        //获取选中的行        var a = $("#table").bootstrapTable('getSelections');        if (a.length == 0) {            alert("请先选中需要修改的项");            return false;        } else if (a.length > 1) {            alert("只能选择一项");            return false;        }        var obj = a[0];        $.ajax({            type: 'post',            data: {                jobId: obj.id            },            url: queryUrl,            success: function (result) {                //刷新表格,状态变更                var opt = {                    url: '${basePath}/scheduleJob/listAllJob.do'                };                $("#table").bootstrapTable('refresh', opt);            }        });    }    //表格详情    function initTable() {        var queryUrl = '${basePath}/scheduleJob/listAllJob.do';        $('#table').bootstrapTable({            method: 'POST',//请求方式(*)            contentType: "application/x-www-form-urlencoded;charset=UTF-8",//在服务端分页时必须配置            dataType: 'json',            //toolbar: '#toolbar',//工具按钮用哪个容器            striped: true,//是否显示行间隔色            cache: false,//是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)            pagination: true,//是否显示分页(*)、            onlyInfoPagination: false,//设置为true时只显示总数据,而不显示分页按钮            showPaginationSwitch: false,            sortable: true,//是否启用排序            sortOrder: "asc",//排序方式            sidePagination: "server",//分页方式:client客户端分页,server服务端分页(*)            pageNumber: 1,//初始化加载第一页,默认第一页,并记录            pageSize: 10,//每页的记录行数(*)            pageList: [10, 25, 50, 100],//可供选择的每页的行数(*)            url: queryUrl,//请求后台的URL(*)            search: false,//是否显示表格搜索            strictSearch: true,            showColumns: false,//是否显示所有的列(选择显示的列)            showRefresh: false,//是否显示刷新按钮            minimumCountColumns: 1,//最少允许的列数            clickToSelect: true,//是否启用点击选中行            //height: 500,                      //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度            uniqueId: "ID",//每一行的唯一标识,一般为主键列            showToggle: false, //是否显示详细视图和列表视图的切换按钮            cardView: false,//是否显示详细视图            detailView: false,//是否显示父子表            paginationDetailHAlign: "left",//设置页面条数信息位置,默认在左边            showExport: false,                     //是否显示导出            exportDataType: "selected",              //basic', 'all', 'selected'.            //获取查询参数            queryParams: function queryParams(params) {                //这里的键的名字和控制器的变量名必须一致,这边改动,控制器也需要改成一样的                var param = {                    pageSize: params.limit,                       //页面大小                    pageNumber: (params.offset / params.limit) + 1,   //页码                    menuName: $("#menuNameQuery").val(), //菜单名称                    parentName: $("#parentNameQuery").val(),//上级菜单名称                };                return param;            },            columns: [                {                    field: 'Number',                    title: '',                    align: 'center',                    width: 20,                    formatter: function (value, row, index) {                        return index + 1;                    }                },                {                    checkbox: true,                    visible: true                  //是否显示复选框                }, {                    field: 'id',                    title: '任务ID',                    width: 50,                    align: 'center'                }, {                    field: 'jobName',                    title: 'JobName',                    width: 150,                    align: 'center'                }, {                    field: 'jobGroup',                    title: 'JobGroup',                    width: 50,                    align: 'center'                }, {                    field: 'beanClass',                    title: 'BeanClass',                    align: 'center'                }, {                    field: 'methodName',                    title: 'MethodName',                    width: 100,                    align: 'center'                }, {                    field: 'params',                    title: '参数',                    width: 100,                    align: 'center'                }, {                    field: 'cronExpression',                    title: 'cron表达式',                    width: 100,                    align: 'center'                }, {                    field: 'status',                    title: '状态',                    width: 50,                    align: 'center',                    formatter: function (value, row, index) {                        if (value == 0) {                            return "<a href='javascript:void(0);' class='btn btn-primary btn-xs'>正常</a>";                        }                        if (value == 1) {                            return "<a href='javascript:void(0);' class='btn btn-danger btn-xs'>暂停</a>";                        }                    }                }, {                    field: 'remark',                    title: '备注',                    width: 100,                    align: 'center'                }],        });    }</script></body></html>

步骤4:定时任务的启动、暂停、时间修改、立即执行

在数据库中我们有设计字段status表示定时任务的状态,0表示正常状态,1表示暂停状态
启动服务器时需要启动status为1的定时任务

4.1 项目启动时启动定时任务

在service在中添加初始化方法,在方法前添加@PostConstruct注解。在方法里面添加调用定时任务的方法

被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的init()方法

4.2 定时任务的时间修改、暂停、立即执行

定时任务的修改、暂停主要是调用quartz内置方法pauseJob()、resumeJob()、triggerJob()等方法

 //暂停一个job JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey);// 恢复一个定时任务JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());scheduler.resumeJob(jobKey);// 立即执行一个定时任务JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());scheduler.triggerJob(jobKey);// 更新时间表达式TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);CronScheduleBuilder scheduleBuilder =                       CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());trigger = trigger.getTriggerBuilder()        .withIdentity(triggerKey)        .build();scheduler.rescheduleJob(triggerKey,trigger);

ScheduleJobServiceImpl

package com.demo.service.impl;import com.demo.common.result.BootstrapTableResult;import com.demo.common.result.Constant;import com.demo.dao.ScheduleJobMapper;import com.demo.domain.ScheduleJob;import com.demo.schedule.QuartzJobFactory;import com.demo.service.ScheduleJobService;import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import org.quartz.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;import javax.annotation.Resource;import java.util.List;/** * @author Administrator * @date 2017-11-21 上午 9:36 */@Service("scheduleJobService")public class ScheduleJobServiceImpl implements ScheduleJobService {    private Logger log = LoggerFactory.getLogger(ScheduleJobServiceImpl.class);    @Resource    private ScheduleJobMapper scheduleJobMapper;    @Resource    private Scheduler scheduler;    public Scheduler getScheduler() {        return scheduler;    }    public void setScheduler(Scheduler scheduler) {        this.scheduler = scheduler;    }    /**     * 项目启动时初始化定时器     */    @PostConstruct    public void init() {        //获取所有的定时任务        List<ScheduleJob> scheduleJobList = scheduleJobMapper.listAllJob();        if (scheduleJobList.size() != 0) {            for (ScheduleJob scheduleJob : scheduleJobList) {                    addJob(scheduleJob);            }        }    }    /**     * 添加任务     * @param job     */    private void addJob(ScheduleJob job) {        try {            log.info("初始化");            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);            //不存在,则创建            if (null == trigger) {                Class clazz = QuartzJobFactory.class;                JobDetail jobDetail = JobBuilder.                        newJob(clazz).                        withIdentity(job.getJobName(), job.getJobGroup()).                        build();                jobDetail.getJobDataMap().put("scheduleJob", job);                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());                //withIdentity中写jobName和groupName                trigger = TriggerBuilder.                        newTrigger().                        withIdentity(job.getJobName(), job.getJobGroup())                        .withSchedule(scheduleBuilder)                        .build();                scheduler.scheduleJob(jobDetail, trigger);                //如果定时任务是暂停状态                if(job.getStatus() == Constant.STATUS_NOT_RUNNING){                    pauseJob(job.getId());                }            } else {                // Trigger已存在,那么更新相应的定时设置                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());                // 按新的cronExpression表达式重新构建trigger                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();                // 按新的trigger重新设置job执行                scheduler.rescheduleJob(triggerKey, trigger);            }        } catch (Exception e) {            log.error("添加任务失败", e);        }    }    /**     * 查询所有的定时任务     * @return BootstrapTableResult     */    @Override    public BootstrapTableResult listAllJob(int pageSize, int pageNumber) {        PageHelper.startPage(pageNumber, pageSize);        List<ScheduleJob> scheduleJobList = scheduleJobMapper.listAllJob();        PageInfo pageInfo = new PageInfo(scheduleJobList, Constant.PAGENUMBER);        int total = (int) pageInfo.getTotal();        BootstrapTableResult bootstrapTableResult = new BootstrapTableResult(total, scheduleJobList);        return bootstrapTableResult;    }    /**     * 暂停定时任务     * @param jobId     */    @Override    public void pauseJob(int jobId) {        //修改定时任务状态        ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);        scheduleJob.setId(jobId);        scheduleJob.setStatus(Constant.STATUS_NOT_RUNNING);        updateJobStatusById(scheduleJob);        try {            //暂停一个job            JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());            scheduler.pauseJob(jobKey);        }catch (Exception e){            log.error("CatchException:暂停任务失败",e);        }    }    /**     * 恢复一个定时任务     * @param jobId     */    @Override    public void resumeJob(int jobId) {        //修改定时任务状态        ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);        scheduleJob.setStatus(Constant.STATUS_RUNNING);        updateJobStatusById(scheduleJob);        try{            //恢复一个定时任务            JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());            scheduler.resumeJob(jobKey);        }catch (Exception e){            log.error("CatchException:恢复定时任务失败",e);        }    }    /**     * 立即执行一个定时任务     * @param jobId     */    @Override    public void runOnce(int jobId) {        try{            ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);            JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());            scheduler.triggerJob(jobKey);        }catch (Exception e){            log.error("CatchException:恢复定时任务失败",e);        }    }    /**     * 更新时间表达式     * @param id     * @param cronExpression     */    @Override    public void updateCron(int id, String cronExpression) {        ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(id);        scheduleJob.setCronExpression(cronExpression);        updateJobCronExpressionById(scheduleJob);        try {            TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();            scheduler.rescheduleJob(triggerKey,trigger);        }catch(Exception e){            log.error("CatchException:更新时间表达式失败",e);        }    }    /**     * 修改定时任务状态     * @param scheduleJob     */    private void updateJobStatusById(ScheduleJob scheduleJob){        scheduleJobMapper.updateJobStatusById(scheduleJob);    }    /**     * 修改定时任务时间     */    private void updateJobCronExpressionById(ScheduleJob scheduleJob){        scheduleJobMapper.updateJobCronExpressionById(scheduleJob);    }    /**     * 通过主键id查找定时任务     * @param id     * @return ScheduleJob     */    private ScheduleJob getScheduleJobByPrimaryKey(int id){        return scheduleJobMapper.getScheduleJobByPrimaryKey(id);    }}

QuartzJobFactory.java

package com.demo.schedule;import com.demo.common.utils.TaskUtils;import com.demo.domain.ScheduleJob;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * @author admin * @date 2017-11-25 下午 21:49 */public class QuartzJobFactory implements Job {    public Logger log = LoggerFactory.getLogger(this.getClass());    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("定时任务运行中...");        ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");        TaskUtils.invokeMethod(scheduleJob);    }}

执行计划任务的代码就在TaskUtils.invokMethod(scheduleJob)里面,通过scheduleJob的beanClass来获得需要执行的类,通过methodName来确定执行哪个方法
定时任务启动后,可以直接修改启动、暂停状态,但是重启服务器时并不会记录当前状态,建议先将修改后的状态保存到数据库status字段中

TaskUtils.java

package com.demo.common.utils;import com.demo.domain.ScheduleJob;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * @author admin * @date 2017-11-21 下午 16:07 */public class TaskUtils {    public static Logger log = LoggerFactory.getLogger(TaskUtils.class);    public static void invokeMethod(ScheduleJob scheduleJob) {        Object object = null;        Class clazz = null;        if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {            try {                clazz = Class.forName(scheduleJob.getBeanClass());                object = clazz.newInstance();            } catch (Exception e) {                log.error("CatchException:",e);            }        }        if (object == null) {            log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");            System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");            return;        }        clazz = object.getClass();        Method method = null;        try {            method = clazz.getDeclaredMethod(scheduleJob.getMethodName());        } catch (NoSuchMethodException e) {            log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");            System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");        } catch (SecurityException e) {            e.printStackTrace();        }        if (method != null) {            try {                method.invoke(object);            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (IllegalArgumentException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }        }        log.info("任务名称 = [" + scheduleJob.getJobName() + "]----------启动成功");    }}

SpringContextUtil.java

package com.demo.common.utils;import org.springframework.beans.BeansException;import org.springframework.beans.factory.NoSuchBeanDefinitionException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;/** * 获取spring容器,以访问容器中定义的其他bean * @author Administrator * @date 2017-11-21 下午 12:39 */@Componentpublic class SpringContextUtils implements ApplicationContextAware {    /**     * Spring应用上下文环境     */    public static ApplicationContext applicationContext;    /**     * 实现ApplicationContextAware接口的回调方法,设置上下文环境     * @param applicationContext     * @throws BeansException     */    @Override    public void setApplicationContext(ApplicationContext applicationContext) {        SpringContextUtils.applicationContext = applicationContext;    }    /**     * 获取对象 这里重写了bean方法,起主要作用     * @param name     * @return Object 一个以所给名字注册的bean的实例     * @throws BeansException     */    public static <T> T  getBean(String name) throws BeansException {        return (T) applicationContext.getBean(name);    }    /**     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true     * @param name     * @return boolean     */    public static boolean containsBean(String name) {        return applicationContext.containsBean(name);    }    /**     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。     * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)     * @param name     * @return boolean     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException     */    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {        return applicationContext.isSingleton(name);    }    /**     * @param name     * @return Class 注册对象的类型     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException     *     */    public static Class<? extends Object> getType(String name) throws NoSuchBeanDefinitionException {        return applicationContext.getType(name);    }    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {        return applicationContext.getAliases(name);    }}

4.3 需要执行的定时任务

TaskTest1.java

package com.demo.schedule;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import java.nio.charset.Charset;import java.util.Map;/** * @author admin * @date 2017-11-25 下午 20:14 */@Componentpublic class TaskTest1 {    public static final Logger LOGGER = LoggerFactory.getLogger(TaskTest1.class);    public void run1(){        System.out.println("执行方法1");    }    public void run2(){        System.out.println("执行方法2");    }    public void run3(){        System.out.println("执行方法3");    }    public void run4(){        System.out.println("执行方法4");    }}

4.4 项目中涉及到的其他文件

Constant.java

/** * 常量类 * @author admin * @date 2017-11-25 19:06 */public class Constant {    /**     * 分页条显示页数     */    public static final int PAGENUMBER = 5;    /**     * 定时任务启动状态     */    public static final int STATUS_RUNNING = 0;    /**     * 定时任务暂停状态     */    public static final int STATUS_NOT_RUNNING = 1;}

BootstrapTableResult.java

/** * bootstrapTable所需的结果集 * @author admin * @date 2017-11-25 18:59 */ public class BootstrapTableResult {    /**     * 总记录数     */    private Integer total;    /**     * 结果集的list集合     */    private List rows;    省略get/set...}

BaseResult.java

/** * 统一返回结果类 * @author Administrator * @date 2017-11-25 下午 20:07 */public class BaseResult {    /**     * 状态码:1成功,其他为失败     */    private int code;    /**     * 成功为success,其他为失败原因     */    private String message;    /**     * 数据结果集     */    public Object data;    省略get/set

ScheduleJob实体类

/** * 定时任务实体类 * @author admin * @date 2017-11-25 下午 19:06 */public class ScheduleJob {    /**     * 主键id     */    private Integer id;    /**     * 任务名     */    private String jobName;    /**     * 任务组     */    private String jobGroup;    /**     * 要执行的方法的名称     */    private String methodName;    /**     * 要执行的方法所在的class路径     */    private String beanClass;    /**     * 定时任务状态,0表示正常,1表示停止     */    private Integer status;    /**     * 时间表达式     */    private String cronExpression;    /**     * 参数     */    private String params;    /**     * 备注     */    private String remark;    /**     * 创建时间     */    private Date createTime;    /**     * 修改时间     */    private Date modifyTime;    省略get/set}

Controller层:ScheduleJobController.java

package com.demo.controller;import com.demo.common.result.BaseResult;import com.demo.common.result.BootstrapTableResult;import com.demo.service.ScheduleJobService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;/** * 定时任务控制层 * @author admin * @date 2017-11-25 18:49 */@Controller@RequestMapping(value = "/scheduleJob")public class ScheduleJobController {    public static Logger log = LoggerFactory.getLogger(ScheduleJobController.class);    @Resource    private ScheduleJobService scheduleJobService;    /**     * 查询所有的定时任务,用于页面加载时显示表格数据     * @param pageSize 每页显示数量     * @param pageNumber 页数     * @return BootstrapTableResult     */    @RequestMapping(value = "/listAllJob", method = RequestMethod.POST)    @ResponseBody    public BootstrapTableResult listAllJob(int pageSize, int pageNumber) {        BootstrapTableResult bootstrapTableResult = scheduleJobService.listAllJob(pageSize, pageNumber);        return bootstrapTableResult;    }    /**     * 暂停定时任务     * @param jobId     * @return BaseResult     */    @RequestMapping(value = "/pauseJob", method = RequestMethod.POST)    @ResponseBody    public BaseResult pauseJob(int jobId) {        scheduleJobService.pauseJob(jobId);        return new BaseResult(1, "success", "定时任务暂停成功");    }    /**     * 恢复定时任务     * @param jobId     * @return BaseResult     */    @RequestMapping(value="/resumeJob",method = RequestMethod.POST)    @ResponseBody    public BaseResult resumeJob(int jobId){        scheduleJobService.resumeJob(jobId);        return new BaseResult(1, "success", "定时任务恢复成功");    }    /**     * 立即执行定时任务     * @param jobId     * @return BaseResult     */    @RequestMapping(value = "/runOnce",method = RequestMethod.POST)    @ResponseBody    public BaseResult runOnce(int jobId){        scheduleJobService.runOnce(jobId);        return new BaseResult(1, "success", "立即执行定时任务成功");    }    /**     * 更新时间表达式     * @param id     * @param cronExpression     * @return BaseResult     */    @RequestMapping(value = "/updateCron",method = RequestMethod.POST)    @ResponseBody    public BaseResult updateCron(int id,String cronExpression){        scheduleJobService.updateCron(id,cronExpression);        return new BaseResult(1, "success", "更新时间表达式成功");    }}

dao层:ScheduleJobMapper.java

package com.demo.dao;import com.demo.domain.ScheduleJob;import java.util.List;/** * 定时任务 * @author admin * @date 2017-11-20 下午 15:52 */public interface ScheduleJobMapper {    /**     * 查询所有的定时任务     * @return List<ScheduleJob>     */    List<ScheduleJob> listAllJob();    /**     * 更新定时任务状态     * @param scheduleJob     */    void updateJobStatusById(ScheduleJob scheduleJob);    /**     * 根据主键查询定时任务     * @param id     * @return ScheduleJob     */    ScheduleJob getScheduleJobByPrimaryKey(int id);    /**     * 更新时间表达式     * @param scheduleJob     */    void updateJobCronExpressionById(ScheduleJob scheduleJob);}

dao实现层:ScheduleJobMapper.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.demo.dao.ScheduleJobMapper">  <resultMap id="BaseResultMap" type="com.demo.domain.ScheduleJob">    <id column="id" property="id" />    <result column="job_name" property="jobName" />    <result column="job_group" property="jobGroup" />    <result column="method_name" property="methodName" />    <result column="bean_class" property="beanClass" />    <result column="status" property="status" />    <result column="cron_expression" property="cronExpression" />    <result column="params" property="params" />    <result column="remark" property="remark" />    <result column="create_time" property="createTime" />    <result column="modify_time" property="modifyTime" />  </resultMap>  <sql id="Base_Column_List">    id, job_name, job_group, method_name, bean_class, status, cron_expression, params,     remark, create_time, modify_time  </sql>    <!-- 查询所有的定时任务 -->    <select id="listAllJob" resultMap="BaseResultMap">        select <include refid="Base_Column_List" /> from schedule_job    </select>    <!-- 更新定时任务状态 -->    <update id="updateJobStatusById" parameterType="ScheduleJob">        update schedule_job SET status = #{status} where id = #{id}    </update>    <!-- 根据主键查询定时任务 -->    <select id = "getScheduleJobByPrimaryKey" resultMap="BaseResultMap">        SELECT * from schedule_job WHERE id = #{id}    </select>    <!-- 修改定时任务时间表达式 -->    <update id="updateJobCronExpressionById" parameterType="ScheduleJob">        UPDATE schedule_job SET cron_expression = #{cronExpression} where id = #{id}    </update></mapper>

service层:ScheduleJobService.java

package com.demo.service;import com.demo.common.result.BootstrapTableResult;import com.demo.dao.ScheduleJobMapper;import org.quartz.Scheduler;import org.springframework.stereotype.Service;import javax.annotation.Resource;/** * @author admin * @date 2017-11-25 18:51 */public interface ScheduleJobService {    /**     * 查询所有的定时任务     * @param pageSize     * @param pageNumber     * @return BootstrapTableResult     */    BootstrapTableResult listAllJob(int pageSize, int pageNumber);    /**     * 暂停定时任务     * @param jobId     */    void pauseJob(int jobId);    /**     * 恢复一个定时任务     * @param jobId     */    void resumeJob(int jobId);    /**     * 立即执行一个定时任务     * @param jobId     */    void runOnce(int jobId);    /**     * 更新时间表达式     * @param id     * @param cronExpression     */    void updateCron(int id, String cronExpression);}

步骤5. 测试

在数据库中添加以下数据
数据库数据

第一条每5秒执行一次,第二条数据每秒执行一次,第三条和第四条数据启动时不执行
启动服务器,控制台输出如下结果
这里写图片描述

修改定时任务1的时间,设置为5秒,查看控制台,可以看到定时任务1和定时任务2都是每5秒执行一次
修改定时任务时间
结果2

暂定、恢复、立即执行这里就不一一测试了,有需要的自行测试(注:立即执行只会执行一次)

源码下载地址:https://gitee.com/seek412/quartz03.git

上一篇:spring整合quartz定时任务(附demo)(二)