zoukankan      html  css  js  c++  java
  • 个人技术总结——关于springboot的定时任务框架quartz

    这个作业属于哪个课程 福大20春软工S班
    这个作业要求在哪里 个人作业——软件工程实践总结&个人技术博客
    这个作业的目标 个人技术总结
    作业正文 正文
    其他参考文献 百度 CSDN博客

    一、技术概述

    1、 该技术的用处在于规范的发布springboot的定时任务,并能方便地对定时任务进行增删改查。

    2、 学习quartz框架的难点在于,springboot的自动注入需要编写quartz的配置类才能完成,这导致我一开始无法自动注入,不能在定时任务类中使用dao层代码,定时任务还运用了corn格式,还有线程池,这些都是难点。

    二、技术详述

    在maven中引入springboot的quartz框架
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
     </dependency>
    
    import org.quartz.Scheduler;
    import org.quartz.spi.TriggerFiredBundle;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.scheduling.quartz.SpringBeanJobFactory;
    
    /**
     * @author: ak
     * @date: 2020/5/6 19:00
     * @description:编写quartz的配置类,这样才能在quartz相关的代码中运用springboot的自动注入
     */
    @Configuration
    public class JobFactory extends SpringBeanJobFactory {
    
        @Autowired
        private AutowireCapableBeanFactory beanFactory;
    
        @Autowired
        private JobFactory jobFactory;
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            Object jobInstance = super.createJobInstance(bundle);
            beanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean() {
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            schedulerFactoryBean.setJobFactory(jobFactory);
            return schedulerFactoryBean;
        }
    
        @Bean(name = "scheduler")
        public Scheduler scheduler() {
            return schedulerFactoryBean().getScheduler();
        }
    }
    
    
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    /**
         * quartz写定时任务业务逻辑的代码,需要继承quartz框架提供的接口job类
         *
         */
    @Component
    public class TaskJob implements Job {
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void execute(JobExecutionContext jobExecutionContext) {
            JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
            String[] key = jobDataMap.getKeys();
            //获取要进行统分的评分表id,以下皆为定时任务要实行的业务逻辑
            int kid = Integer.parseInt(jobDataMap.getString(key[0]));
            System.out.println("正在统分....");
            statEvaluationOuter(kid);
            statEvaluationInner(kid);
            System.out.println("任务结束...");
        }
    
    /**
         * quartz用于发布定时任务的代码
         *
         * @param cron      任务周期
         * @param startTime 开始时间
         * @param endTime   结束时间
         * @param tableDataKey   指定定时任务的ID
         * @param tableData   指定定时任务需要的数据
         */
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
        @Autowired
        Scheduler scheduler;
    
        public void publishTask(String cron, long startTime, long endTime, String tableDataKey, String tableData) throws SchedulerException {
            try {
                Scheduler scheduler = this.scheduler;
                //创建JobDetail实例,并与TaskJob类绑定(Job执行内容),TaskJob类代码在上面
                JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
                        .withIdentity("job-" + tableDataKey, "group-" + tableDataKey).build();
                //指定周期性定时任务
                CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                        .withIdentity("trigger-" + tableDataKey, "triggerGroup-" + tableDataKey)
                        .usingJobData(tableDataKey, tableData)
                        .startNow()//立即生效
                        .startAt(new Date(startTime))
                        .endAt(new Date(endTime))
                        .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                        .build();
    
                //执行
                scheduler.scheduleJob(jobDetail, cronTrigger);
                System.out.println("--------定时任务发布成功 ! ------------");
                System.out.println(cronTrigger.getJobDataMap().get(tableDataKey));
                System.out.println("当前任务key:" + tableDataKey);
                scheduler.start();
    
            } catch (SchedulerException e) {
                throw e;
            }
        }
    

    通过编写上述的Job类和发布任务的方法,只要使用publishTask方法,就可以对定时任务进行发布了,当然quartz还能进行任务的修改,删除和查找,使用方法就像数据库一样,很相似,在这里就不过多赘述,想看的可以看github上的代码:

    定时任务的增删改查代码

    三、遇到的困难和解决

    1、 首先是springboot的自动注入问题,quartz框架由于发布定时任务的时候会在springboot注入容器之前,所以如果不编写配置类会发现自动注入的对象是null的情况。我的定时任务中要对数据库进行修改,但是在定时任务的Job类中自动注入的dao层代码一直是null,导致我无法在Job类中对数据库进行操作。最终我查阅资料,知道了要编写quartz框架的配置类,解决办法就是增加配置类代码,代码在第二点技术详述里面有。

    2、对于corn和时间戳的使用。一开始我不懂corn和时间戳都是什么,在使用quartz进行时间规定的时候遇到了困难,这边推荐两个博客,很好的解决了我的疑问

    corn表达式的使用方法

    java中的时间和时间戳

    四、总结

    总的来说,quartz是个很强大的定时任务框架,springboot的原生定时任务注解不能很好的管理定时任务,但是quartz框架会帮助你管理好定时任务的线程池,比较方便地进行定时任务的增删改查,只要将小问题解决了,就尽管编写业务逻辑代码,并进行定时任务的发布与管理即可,是相当强大的一个框架。

    五、参考文献

    corn表达式的使用方法 作者:西班牙乞丐

    java中的时间和时间戳 作者:小小舍

    SpringBoot2.1 - Quartz自动化配置集成 yml方式配置免配置类和properties 作者:ataopro

  • 相关阅读:
    Windows Server 2003安装VS2010重命名项目崩溃
    分表处理设计思想和实现[转载]
    XSD中如何定义节点(Element)包含属性(Attribute)和上下文(Context)?
    数据库水平切分的原理探讨、设计思路数据库分库,分表,集群,负载均衡器
    域名注册供参考的200个前缀和后缀
    一个 XSD 实例
    了解Javascript中defer
    Asp.net中慎用Page.DataBind()
    C#中相对路径转绝对路径
    Cookies中Secure使用
  • 原文地址:https://www.cnblogs.com/bkmemory/p/13162806.html
Copyright © 2011-2022 走看看