quartz1.8+spring2.3.9实现从数据库中读取定时任务

数据库建表语句

CREATE TABLE `report_tasks_manager` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `task_desc` varchar(255) DEFAULT NULL COMMENT '任务描述',
  `task_name` varchar(100) NOT NULL COMMENT '任务名称',
  `cron_expression` varchar(20) DEFAULT NULL COMMENT '任务执行表达式',
  `method_name` varchar(20) DEFAULT NULL COMMENT '要执行的方法名',
  `state` int(3) NOT NULL COMMENT '任务状态 0加入任务1取消任务',
  `con_current` int(3) DEFAULT NULL COMMENT '是否并发执行 0并发1不并发',
  `reserved1` varchar(32) DEFAULT NULL COMMENT '预留字段',
  `reserved2` varchar(32) DEFAULT NULL COMMENT '预留字段2',
  `reserved3` varchar(32) DEFAULT NULL COMMENT '预留字段3',
  `start_time` datetime DEFAULT NULL COMMENT '任务开始执行时间',
  `end_time` datetime DEFAULT NULL COMMENT '任务结束时间',
  `create_time` datetime DEFAULT NULL COMMENT '任务创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `task_name` (`task_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

设计思路

流程说明:
定时任务在后台开启,读取数据库中的任务信息(任务类,执行方法,执行时间等),判断定时触发器(trigger)中是否存在该任务。
  1.1 如果存在该任务,比较数据库中的任务表达式(cron)是否与当前定时器中的时间一致。
    1.1.1 如果不一致,更新当前任务时间表达式。
    1.1.2 如果一致,跳至方法3。 
  1.2 如果不存在该任务,跳至方法2。
2. 如果不存在该任务,加入定时器任务中。 
3.触发定时任务,执行定时任务方法。
流程图

代码详解

主要包括spring的配置文件和java类的设计。

spring配置文件

     <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="1" />
        <property name="maxPoolSize" value="20" />
        <property name="queueCapacity" value="100" />
        <property name="keepAliveSeconds" value="2000" />
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$AbortPolicy" />
        </property>
    </bean>

    <bean id="quartzManager" class="com.wasu.upm.report.quartz.QuartzManager">
        <property name="scheduler" ref="schedulerManager" />
    </bean>
    <bean id="quartzManagerJobDetail"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="quartzManager" />
        <property name="targetMethod" value="reScheduleJob" />
        <property name="concurrent" value="false" />
    </bean>
    <bean id="cronTriggerBean" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        <property name="jobDetail" ref="quartzManagerJobDetail" />
        <!-- 延时1秒 执行任务 -->
        <property name="startDelay" value="0"/>
        <!-- 任务执行周期 20m -->
        <property name="repeatInterval" value="20000" />
    </bean>
    <!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  -->
    <bean id="schedulerManager" lazy-init="false" autowire="no"
          class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTriggerBean" />
            </list>
        </property>
        <property name="taskExecutor" ref="taskExecutor"/>
    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

解释说明:
taskExecutor:设置任务的并发数量。例如我们想让线程单线程执行,即taskA开始执行–>taskA执行结束;taskB开始执行–>taskB执行结束;
quartzManager:定义一个定时任务,来进行其他定时任务的管理。
quartzManagerJobDetail:具体的任务类定义执行的方法。以及该任务是否并发执行。 
concurrent=false指该任务不并发执行,为true指并发执行。
cronTriggerBean:设置执行的时间。

quartzManager管理类

package com.wasu.upm.report.quartz;

import java.util.Date;
import java.util.List;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import com.wasu.upm.commons.bo.ReportTasksManagerBo;
import com.wasu.upm.report.service.IReportManagerService;

public class QuartzManager implements BeanFactoryAware{
    private final static Logger log = LoggerFactory
            .getLogger(QuartzManager.class);
    private Scheduler scheduler;

    /**每隔1小时执行一次
    */
    private static final String DEFAULT_CRON="* * */1 * * ?";
    @Autowired
    private IReportManagerService reportManagerService; 
    private static BeanFactory beanFactory;

    public Scheduler getScheduler() {
        return scheduler;
    }

    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }


    /**
     * 定时要执行的方法类。
     */
    public void reScheduleJob(){
        // 1.读取数据库中的任务列表,状态为0的任务。
        Date currentDate = new Date();
        List<ReportTasksManagerBo> expireList = reportManagerService.findExpireTasks(currentDate);
        if(expireList!=null && expireList.size()>0){
            for(ReportTasksManagerBo bo : expireList){
                //配置任务列表
                removeExpireTasks(bo);
            }
        }
        List<ReportTasksManagerBo> list = reportManagerService.findTasks(currentDate);
        if(list==null||list.size()==0){
            log.warn("查询的任务列表为空");
            return;
        }
        for(ReportTasksManagerBo bo : list){
            //配置任务列表
            configSchedul(bo);
        }
    }
    /**
     * 移除过期任务
     * @param bo
     */
    private void removeExpireTasks(ReportTasksManagerBo bo) {
        try {
            CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(bo.getTaskName(), Scheduler.DEFAULT_GROUP);
            if(trigger!=null){
                System.out.println("==移除任务=="+bo.getTaskName());
                scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());// 停止触发器
                scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());// 移除触发器
                scheduler.deleteJob(trigger.getJobName(), trigger.getJobGroup());// 删除任务
            }
        } catch (SchedulerException e) {
            log.error("移除任务失败...");
            e.printStackTrace();
        }
    }

    /**
     * 配置任务列表
     * @param bo
     */
    private void configSchedul(ReportTasksManagerBo bo) {
        try {
            CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(bo.getTaskName(), Scheduler.DEFAULT_GROUP);
            if(trigger==null){//说明schedule中不存在该定时任务
                createTriggerTask(bo);
            }else{
                updateTriggerTask(bo,trigger);
            }
        } catch (SchedulerException e) {
            log.error("获取触发器trigger失败...");
            e.printStackTrace();
        }
    }
    /**
     * 更新任务列表
     * @param bo
     */
    private void updateTriggerTask(ReportTasksManagerBo bo,CronTriggerBean trigger) {
        if(bo.getState()==0){
            try{
                // 判断从DB中取得的任务时间和现在的quartz线程中的任务时间是否相等
                // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob
                if(trigger.getCronExpression()!=null&&
                        !trigger.getCronExpression().equalsIgnoreCase(bo.getCronExpression())) {
                    System.out.println("=真正更新方法:="+bo.getTaskName());
                    trigger.setCronExpression(bo.getCronExpression());
                    scheduler.rescheduleJob(bo.getTaskName(),Scheduler.DEFAULT_GROUP, trigger);
                    log.info("更新任务时间失败...");
                }
            }catch(Exception e){
                log.error("更新任务时间失败...");
                e.printStackTrace();
            }
        }else{
            this.removeExpireTasks(bo);
        }
    }
    /**
     * 创建任务列表
     * @param bo
     */
    private void createTriggerTask(ReportTasksManagerBo bo) {
        if(bo.getState()==0){
            System.out.println("=创建:="+bo.getTaskName());
            MethodInvokingJobDetailFactoryBean mjdfb = new MethodInvokingJobDetailFactoryBean();
            mjdfb.setBeanName(bo.getTaskName());
            try{
                Object obj = beanFactory.getBean(bo.getTaskName());
                mjdfb.setTargetObject(obj);
                mjdfb.setTargetMethod(bo.getMethodName());
                boolean isConcurrent=false;
                if(bo.getConCurrent()==0){
                    isConcurrent = true;
                }
                mjdfb.setConcurrent(isConcurrent);
                mjdfb.afterPropertiesSet(); //将管理Job类提交到计划管理类
                JobDetail jobDetail = new JobDetail();
                jobDetail = mjdfb.getObject();
                jobDetail.setName(bo.getTaskName());
                scheduler.addJob(jobDetail, true); // 将Job添加到管理类
                String cronExpression=null;
                if(bo.getCronExpression()==null||"".equals(bo.getCronExpression())){
                    cronExpression=DEFAULT_CRON;
                }else{
                    cronExpression = bo.getCronExpression();    
                }
                // 新一个基于Spring的时间类
                CronTriggerBean c = new CronTriggerBean();
                c.setCronExpression(cronExpression);// 设置时间表达式
                c.setName(bo.getTaskName());// 设置名称
                c.setJobDetail(jobDetail);// 注入Job
                c.setJobName(bo.getTaskName());// 设置Job名称
                scheduler.scheduleJob(c);// 注入到管理类
                scheduler.rescheduleJob(bo.getTaskName(), Scheduler.DEFAULT_GROUP,c);// 刷新管理类
            }catch(Exception e){
                log.error("创建"+bo.getTaskName()+"任务失败...");
                e.printStackTrace();
            }
        }else{
            this.removeExpireTasks(bo);
        }
    }


    public void setBeanFactory(BeanFactory factory) throws BeansException {
        this.beanFactory = factory;

    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }   
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
护和治理 强化环境保护和治理是实现低碳发展的重要保障,它可以好的,您想了解如何使用Quartz 2.3.2和Spring Boot实现数据库持久化存储保护自然环境,减少环境污染和碳排放。为了强化环境保护和治理多个定时任务。下面是具体的实现步骤: 1. 在pom.xml文件添加Quartz和,需要政府加大对环境保护和治理的资金和政策支持,同时也需要企业加Spring JDBC的依赖: ```xml <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>强对环境保护和治理的责任和义务,营造良好的生态环境。 四、结quartz</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org论 随着全球环境问题的不断加剧,低碳发展已经成为各国共同关注.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.8</version> </dependency> ``` 2. 配置Quartz的数据源和Spring的JdbcTemplate: ```java @Configuration public class QuartzConfig { 的重要话题。数据科学与大数据技术在低碳发展发挥着越来越重要的 @Bean public DataSource quartzDataSource() { // 配置数据源 return DataSourceBuilder.create() .driverClassName作用,通过数据科学和大数据技术的应用,可以更加精准地监测、分析和预("com.mysql.cj.jdbc.Driver") .url("jdbc:mysql://localhost:3306/quartz") .username("root") 测碳排放情况,制定更加科学、可行的低碳发展规划,推动能源结 .password("123456") .build(); } @Bean public JdbcTemplate jdbcTemplate() { // 配置Spring的构转型升级,促进低碳技术的应用和发展。为了实现低碳发展的目JdbcTemplate return new JdbcTemplate(quartzDataSource()); } } ``` 3. 创建定时任务实体类: ```java @Data @AllArgsConstructor @NoArgsConstructor public class QuartzJob { private String jobName; private String jobGroup; private String cron标,需要政府、企业和公众共同努力,推动低碳发展进程,实现经济社会可持续发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值