QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)

简介

  • Quartz介绍
  • 成果展示
  • QiYuAdmin集Quartz
  • Quartz的API封装和数据库设计
  • 页面和功能开发

Quartz介绍

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。

成果展示

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第1张图片

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第2张图片

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第3张图片

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第4张图片

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第5张图片

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第6张图片

QiYuAdmin集成Quartz

  • 父pom文件(控制继承)
    
        <dependency>
               <groupId>org.quartz-schedulergroupId>
               <artifactId>quartzartifactId>
               <version>${quartz.version}version>
        dependency>
     dependencyManagement>
  • 子pom文件(引用)
    
         <groupId>org.quartz-schedulergroupId>
         <artifactId>quartzartifactId>
    dependency>

Quartz的API封装和数据库设计

这里没有用SpringBoot集成Quartz的javaconfig模式配置,网上也有:SpringBoot集成Quartz
这里我引用了之前公司老项目的做法,单节点不是集群,配置的简单了点。后续研究研究集群环境的Quartz。现在的做法是先在数据库里面创建表

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第7张图片

然后将定时器给启动起来,启动定时器的地方可以放在服务器启动的时候,我们这里就先放在当点击菜单《定时器》的时候触发启动定时器。当点击菜单《定时器》的时候触发的步骤是:
1. 开启定时器
2. 从数据库里面查询所有任务列表
3. 将这些任务列表放在定时器(Schedule)里面
4. 根据数据库存储的任务状态来进行启停服务

 SchedulerManager.start();//开启定时器
        //注册所有任务到scheduler里面,并根据scheduler的状态来开启任务
        List schedulerList = schedulerMapper.selectAll();
        if(HelpUtils.isNotEmpty(schedulerList)){
            for(SystemScheduler scheduler :schedulerList){
                SchedulerManager.addScheduler(scheduler);//将任务放在定时器里面并根据状态启停服务
            }
        }
        pageNo = pageNo == null?1:pageNo;
        pageSize = pageSize == null?10:pageSize;
        PageHelper.startPage(pageNo,pageSize);  //startPage是告诉拦截器说我要开始分页了。分页参数是这两个。
        return BeanUtil.toPagedResult(schedulerMapper.selectByCondition(systemScheduler));

以上代码开启定时器方法和添加一个任务的方法封装到了SchedulerManager里面了。添加完任务到scheduler中之后在根据数据库查询出来的isStart进行启停服务。
开启服务代码:

public static void start(){
        quartzManager.startJobs();
}

    public void startJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            if (!sched.isStarted()) {
                sched.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

增加任务到定时器里面并根据数据库的状态来启停服务器代码:

    public static void addScheduler(SystemScheduler scheduler) {
        addOrModify(scheduler);
    }


    private static void addOrModify(SystemScheduler scheduler) {
        // job类处理
        Class jobclass = verify(scheduler);
        // 添加到调度器
        if (!HelpUtils.isEmpty(jobclass)) {
            if (quartzManager.isExist(getJobName(scheduler))) {// 存在
                quartzManager.modifyJobTime(getJobName(scheduler), scheduler.getCron(),
                        quartzManager.getJobDataMap(scheduler.getJobParams()));
            } else {// 不存在
                quartzManager.addJob(getJobName(scheduler), jobclass, scheduler.getCron(),
                        quartzManager.getJobDataMap(scheduler.getJobParams()));
            }
            pauseJob(scheduler);//根据状态启停服务
        }
    }

public static void pauseJob(SystemScheduler scheduler) {
        String jobName = getJobName(scheduler);
        if (scheduler.getIsStart().equalsIgnoreCase("1")) {// 开启一个任务
            quartzManager.resumeJob(jobName);
        } else if (scheduler.getIsStart().equalsIgnoreCase("0")) {// 暂停一个任务
            quartzManager.pauseJob(jobName);
        }
    }

QuartzManager、SchedulerManager两个文件放在云盘上。下载

页面和功能开发

不知不觉中,也有了几个模块了(用户、部门、会话、菜单、定时器)

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第8张图片

主界面代码如下:

QiYuAdmin-Quartz定时器动态启停服务(SpringBoot项目实战)_第9张图片

scheduler.js代码如下,基本的套路和之前的用户一样,看下应该就明白了。

//@ sourceURL=scheduler.js
/**
 * 定时器模块js:包括主界面、修改定时器界面
 */
var QiYuScheduler = function () {
    //定时任务主页面属性开始
    var schedulerTableId = "schedulerTable";
    var $schedulerTable=$("#schedulerTable");
    var tableAjaxUrl="scheduler/page/list";
    var schedulerTableTableColum=[{checkbox: true}
                        ,{title: 'id',field: 'id',align: 'center',valign: 'middle',visible:false}
                        ,{title: '任务名称',field: 'jobName',align: 'center',valign: 'middle'}
                        ,{title: '任务状态',field: 'isStart',align: 'center',valign: 'middle'}
                        ,{title: 'cron表达式',field: 'cron',align: 'center',valign: 'middle'}
                        ,{title: '创建人',field: 'createBy',align: 'center',valign: 'middle'}
                        ,{title: '创建时间',field: 'createDate',align: 'center',valign: 'middle'}
                        ,{title: '修改人',field: 'updateBy',align: 'center',formatter:function (value,row,index){
                            if(null==value || ""==value){
                                return "-";
                            }
                            return value;
                        }}
                        ,{title: '修改日期',field: 'gender',align: 'center',valign: 'middle',formatter:function (value,row,index) {
                                if(null==value || ""==value){
                                    return "-";
                                }
                                return new Date(value).format("yyyy-MM-dd hh:mm:ss");
                            }}
                        ];
    var $startSchedulers=$("#startSchedulers");
    var $stopSchedulers=$("#stopSchedulers");
    var $updateSchedulerView=$("#updateSchedulerView");
    //定时任务主页面属性结束
    //定时任务修改页面属性
    var $updateSchedulerForm =$("#schedulerUpdateForm");
    var updateSchedulerForm ="schedulerUpdateForm";
    var $updateSchedulerBtn = $("#updateSchedulerBtn");
    var updateAjaxUrl = QiYuComponents.getContextPath()+"/scheduler";
    /**
     * 定时器主页面初始化定时器表格数据
     */
    var initTable=function () {
        QiYuComponents.initBootStrapTable($schedulerTable,tableAjaxUrl,schedulerTableTableColum);
    }
    /**
     * 定时器主页面按钮绑定事件:启动、修改、停止
     */
    var schedulerMainEventHandler=function () {

        //绑定修改定时任务弹出页面的按钮事件
        $updateSchedulerView.on("click",function () {
           var rows =  QiYuComponents.getTableSelections($schedulerTable);
            if(rows.length==0){
                QiYuComponents.bootstrapSweetAlert("","请选择一个定时任务","error");
                return;
            }
            if(rows.length>=2){
                QiYuComponents.bootstrapSweetAlert("","不能选择多个定时任务","error");
                return;
            }
            //查看的基定时器本信息
            QiYuComponents.layerOpen("配置定时器",'900px','450px',"scheduler/update/view/"+rows[0].id);
        });

        //绑定停止定时器事件---------可以和下面的事件绑定合成一个,后续优化
        $stopSchedulers.on("click",function () {
            var rows =  QiYuComponents.getTableSelections($schedulerTable);
            if(rows.length==0){
                QiYuComponents.bootstrapSweetAlert("","请选择一个定时器","error");
                return false;
            }
            if(rows.length==1){
                var isStart = rows[0].isStart;
                if(isStart=="关闭"){
                    QiYuComponents.bootstrapSweetAlert("","此任务已经关闭","error");
                    return false;
                }
            }
            if(rows.length > 1){
                var isStartDataAry=[];
                $.each(rows, function(i, obj) {
                    isStartDataAry.push(obj.isStart);
                });
                var flag = $.inArray("开启", isStartDataAry);
                if(flag==-1){
                    QiYuComponents.bootstrapSweetAlert("","所选择的任务已经全部关闭了","error");
                    return false;
                }
            }
            var idDataAry=[];
            $.each(rows, function(i, obj) {
                if(obj.isStart=="开启"){
                    idDataAry.push(obj.id);
                }
            });
            ajaxChangeJobStatus(idDataAry,"scheduler/status/0");
        });


        //绑定开启定时器事件
        $startSchedulers.on("click",function () {
            var rows =  QiYuComponents.getTableSelections($schedulerTable);
            if(rows.length==0){
                QiYuComponents.bootstrapSweetAlert("","请选择一个定时器","error");
                return false;
            }
            if(rows.length==1){
                var isStart = rows[0].isStart;
                if(isStart=="开启"){
                    QiYuComponents.bootstrapSweetAlert("","此任务已经开启","error");
                    return false;
                }
            }
            if(rows.length > 1){
                var isStartDataAry=[];
                $.each(rows, function(i, obj) {
                    isStartDataAry.push(obj.isStart);
                });
                var flag = $.inArray("关闭", isStartDataAry);
                if(flag==-1){
                    QiYuComponents.bootstrapSweetAlert("","所选择的任务已经全部开启了","error");
                    return;
                }
            }
            var idDataAry=[];
            $.each(rows, function(i, obj) {
                if(obj.isStart=="关闭"){
                    idDataAry.push(obj.id);
                }
            });
            ajaxChangeJobStatus(idDataAry,"scheduler/status/1");
        });
    }

    var ajaxChangeJobStatus = function(idDataAry,url){
        $.ajax({
            type:"POST",
            url:url,
            contentType: "application/json",//加入contentType,后端需要用requestBody接受参数,此时的参数不在request里面了
            data: JSON.stringify(idDataAry),
            dataType: "json",
            success:function(responseJson){
                if(responseJson.success==true){//返回true
                    QiYuComponents.bootstrapSweetAlert("",responseJson.msg,"success");
                    QiYuComponents.refreshTable($schedulerTable);
                }
                if(responseJson.success==false){//返回false
                    QiYuComponents.bootstrapSweetAlert("",responseJson.msg,"error");
                }
            },
            beforeSend:function(XMLHttpRequest){
                //请求之前方法增强处理 ,显示遮罩层
                App.blockUI({target: '.page-content',animate: true});
            },
            complete:function(XMLHttpRequest, textStatus){
                //请求结束方法增强处理  ,隐藏遮罩层
                App.unblockUI('.page-content');
            },
            error:function (XMLHttpRequest, textStatus) {
                QiYuComponents.bootstrapSweetAlert("","请联系管理员!","error");
            }
        });
    }

    /**
     * 定时任务修改页面验证表单
     */
    var initUserUpdateBootStrapValidate = function () {
        $updateSchedulerForm.bootstrapValidator({
//          trigger: 'blur',
            feedbackIcons: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                jobName: {
                    validators: {
                        notEmpty: {
                            message: '任务名称不能为空'
                        }
                    }
                },
                jobClass:{
                    validators: {
                        notEmpty: {
                            message: '类不能为空'
                        }
                    }
                },
                cron:{
                    validators: {
                        notEmpty: {
                            message: 'cron表达式不能为空'
                        }
                    }
                }
            }
        }).on("success.form.bv",function(e){
            QiYuComponents.qiYuAjaxFormSumbitTable(updateAjaxUrl,updateSchedulerForm,schedulerTableId);
        });
    }

    var schedulerUpdateEnventHandler = function () {
        $updateSchedulerBtn.on("click",function () {
            $updateSchedulerForm.submit();
        });
    }
    return{
        //初始化主界面
        initSchedulerMain:function () {
            initTable();
            schedulerMainEventHandler();
        },
        initSchedulerUpdate:function () {
            initUserUpdateBootStrapValidate();
            schedulerUpdateEnventHandler();
        }
    }
}();

简介

收工。

你可能感兴趣的:(QiYuAdmin从0到1)