Dynamic Quartz

​ 最近在公司实习,发现公司有一套spring+Quartz的动态任务管理系统。可以使用Web界面进行任务动态的创建、删除、停止、运行和修改。刚好最近在学习spring boot。便使用spring boot2+quartz+thymeleaf+mysql数据库实现了一个简单的动态任务管理系统。

项目使用方法:

使用IDEA打开该项目,并把application.properties中数据信息修改为自己的数据信息即可。同时把sql文件夹下的sql文件导入到数据中即可。项目地址:http://localhost:8080/

项目地址Github地址:Quartz动态任务调度系统

项目如下图所示:

Quartz

quartz是一个java编写的开源任务调度框架其主要调度元素有:

  • Trigger(触发器):触发任务任务执行的时间或规则。在任务调度Quartz中,Trigger主要的触发器有:SimpleTrigger,CalendarIntervelTrigger,DailyTimeIntervalTrigger,CronTrigger
  • Scheduler(任务调度器):Scheduler就是任务调度控制器,需要把JobDetail和Trigger注册到schedule中,才可以执行 ;Scheduler有两个重要组件:ThreadPool和JobStore。
  • Job(任务):是一个接口,其中只有一个execute方法。开发者只要实现接口中的execute方法即可。
  • JobDetail(任务细节):Quartz执行Job时,需要新建Job实例,但不能直接操作Job类,所以通过JobDetail获得Job的名称,描述信息。

对象之间的关系图如图下图所示:

Spring boot2集成quartz

  1. 添加quartz依赖

    <dependency>
    <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
  2. 添加spring boot2的web 、thymeleaf、依赖

    <!--web相关的依赖-->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--添加集成Thymeleaf的依赖-->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    其他详情依赖请具体间github项目的pom文件。

  3. 相关属性的配置文件。

    
    # 数据库连接的配置spring.datasource.druid.url=jdbc:mysql://localhost:3306/dynamicquartz?useUnicode=true&characterEncoding=utf8
    spring.datasource.druid.username=root
    spring.datasource.druid.password=2012061128
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.filters=stat
    spring.datasource.druid.max-active=20
    spring.datasource.druid.initialSize=1
    spring.datasource.druid.max-wait=60000
    spring.datasource.druid.min-idle=1
    spring.datasource.druid.time-between-eviction-runs-millis=60000
    spring.datasource.druid.min-evictable-idle-time-millis=300000
    spring.datasource.druid.validation-query=select 'x'
    spring.datasource.druid.test-while-idle=true
    spring.datasource.druid.test-on-return=false
    spring.datasource.druid.test-on-borrow=false# mybatis配置mybatis.mapper-locations=classpath:mapper/*.xml
    mybatis.type-aliases-package=cn.bupt.zcc.dynamicquartz.model# quartz的一些属性配置spring.quartz.job-store-type=jdbc
    spring.quartz.properties.org.quartz.scheduler.instanceName=clusteredScheduler
    spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
    spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
    spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_#spring.quartz.properties.org.quartz.jobStore.isClustered=true#spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000spring.quartz.properties.org.quartz.jobStore.useProperties=false# 集成thymeleaf引擎的一些配置spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.check-template-location=true
    spring.thymeleaf.suffix=.html
    spring.thymeleaf.encoding=UTF-8
    spring.thymeleaf.servlet.content-type=text/html
    spring.thymeleaf.mode=HTML5
    spring.thymeleaf.cache=false
  4. 创建quartz任务工厂类:QuartzJobFactory。

    /**
    * @author: Zhang Chengcheng
    * @create: 2018-05-31 14:38
    **/
    @Service("quartzJobFactory")
    public class QuartzJobFactory extends QuartzJobBean {@AutowiredQuartzService quartzService;@Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {ScheduleJob object = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");if(object.getMethodName()==null || object.getMethodName().equals("")){quartzService.executeTask(object.getBeanName());}else {quartzService.executeTask(object.getBeanName(),object.getMethodName());}}
    }

    这是一个任务工厂类继承了QuartzJobBean类。每动态的添加一个定时任务就是创建此类的实例。并把要执行的定时任务类的名称或者全限定类名以及要执行的方法名传入。QuartzService获取传入的spring bean的名称或者全限定类名,获取该任务类的名称并使用反射来调用method,执行任务。通过反射的方式把要执行的任务类和Job接口或者QuartzJobBean类进行解耦。任务类无需实现Job接口或者集成QuartzJobBean类。即可实现任务的动态调度了。

  5. QuartzService实现类如下:

    /**
    * @author: Zhang Chengcheng
    * @create: 2018-05-31 15:34
    **/
    @Service("quartzService")
    public class QuartzServiceImpl implements QuartzService {private static final Logger logger = LoggerFactory.getLogger(QuartzServiceImpl.class);private static final String METHODNAME = "execute";@Overridepublic void executeTask(String beanName, String methodName) {Object object = ApplicationContextUtil.getBean(beanName);try {logger.info("[QuartzServiceImpl] 反射调beanName:{},methodName:{}法开始.........",beanName,methodName);if (beanName.contains("\\.")){Class clazz = Class.forName(beanName);Object cronJob =  ApplicationContextUtil.getBean(clazz);Method method1 = clazz.getMethod(methodName);method1.invoke(cronJob);}else {Method method = object.getClass().getMethod(methodName);method.invoke(object);}} catch (Exception e) {logger.error("[QuartzServiceImpl] method invoke error,beanName:{},methodName:{}",beanName,methodName);return;}logger.info("[QuartzServiceImpl] 反射调beanName:{},methodName:{}法结束.........",beanName,methodName);}
  6. ApplicationContextUtil是一个获取spring bean实例的工具类

    /**
    *
    * @author: Zhang Chengcheng
    * @create: 2018-05-31 15:07
    **/
    @Component("ApplicationContextUtil")
    public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ApplicationContextUtil.applicationContext = applicationContext;}public ApplicationContext getApplicationContext(){checkApplicationContext();return applicationContext;}public void checkApplicationContext(){if (applicationContext==null){throw new IllegalStateException("applicationContext 未注入,请在applicationContext.xml中定义SpringContextUtil");}}/***根据bean的名称去寻找一个类的实例* @param name* @param <T>* @return*/public static <T> T getBean(String name){return (T) applicationContext.getBean(name);}
    }

    ApplicationContextUtil类通过实现ApplicationContextAware接口,获取applicationContext上下文。从而在反射中获取任务的实例。再通过反射来执行任务。

  7. 动态添加任务

    private void addJob(ScheduleJob scheduleJob) throws Exception{checkNotNull(scheduleJob);if (StringUtils.isBlank(scheduleJob.getCronExpression())){throw new Exception("[SchedulerJobServiceImpl] CronExpression不能为空");}scheduleJob.setJobStatus("NORMAL");int id = scheduleJobInService.insertSelective(scheduleJob);logger.info("[SchedulerJobServiceImpl] the Primary key is:{}",scheduleJob.getId());scheduleJob.setJobId(scheduleJob.getId()+"");logger.info("[SchedulerJobServiceImpl] the scheduleJob is:{}",scheduleJob);scheduleJobInService.updateByPrimaryKey(scheduleJob);JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()).build();//创建JobDetail,job是通过QuartzJobFactory.class工厂类反射创建的。jobDetail.getJobDataMap().put("scheduleJob",scheduleJob);CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()).withSchedule(cronScheduleBuilder).build();//创建触发器scheduler.scheduleJob(jobDetail,cronTrigger);//注册jobDetail和Trigger进行任务调度。}
  8. 我们使用web的界面来实现任务的动态的添加。使用的是thymeleaf引擎。

参考:

https://github.com/jiwenxing/springboot-quartz “springboot-quartz”

https://www.jianshu.com/p/5995937f27bc “Quartz教程”

https://blog.csdn.net/u012907049/article/details/73801122 “Spring Boot集成持久化Quartz定时任务管理和界面展示”

Spring boot2集成quartz动态任务管理+Web UI相关推荐

  1. Spring Boot集成Quartz动态实现数据库任务

    1. Quartz简介 1.1. 什么是Quartz Quartz是一个开源的任务调度框架.作用是基于定时.定期的策略来执行任务. 它是OpenSymphony开源组织在Job scheduling领 ...

  2. java quartz 动态执行,浅谈SpringBoot集成Quartz动态定时任务

    SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling @Schedule ...

  3. Spring Boot集成Quartz-动态任务管理

    Quartz提供了一组丰富的API,来管理Job. 前言 当定时任务越来越多时,集中管理Job越有必要.Quartz提供了一组丰富的API,来管理Job. Spring Boot 定时任务之Quart ...

  4. Spring Boot 集成 WebFlux 开发 Reactive Web 应用

    Spring Boot 集成 WebFlux 开发 Reactive Web 应用 <Spring Boot 实战开发>-- 基于 Gradle + Kotlin的企业级应用开发最佳实践 ...

  5. SpringBoot集成Quartz动态定时任务

    SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling @Schedule ...

  6. springboot集成kafka及kafka web UI的使用

    springboot集成kafka application.properties spring.kafka.bootstrap-servers=CentOSA:9092,CentOSB:9092,Ce ...

  7. Spring Boot集成Quartz注入Spring管理的类

    摘要: 在Spring Boot中使用Quartz时,在JOB中一般需要引用Spring管理的Bean,通过定义Job Factory实现自动注入. Spring有自己的Schedule定时任务,在S ...

  8. Spring Boot 集成Quartz

    1:在项目的pom文件添加quartz依赖 <!-- quartz定时任务 --> <dependency><groupId>org.springframework ...

  9. mysql的每隔1分钟定时_简单易用,spring boot集成quartz,实现分布式定时任务

    什么是quartz? Quartz是一个完全由 Java 编写的开源任务调度框架. 我们经常会遇到一些问题: 想每个月27号,提醒信用卡还款: 想每隔1小时,提醒一下,累了,站起来活动一下: 想每个月 ...

最新文章

  1. js控制使div自动适应居中
  2. 微软MVP社区活动(西宁站)
  3. 计算机组成 面试 ---杂货铺
  4. 016_泛型常见通配符
  5. Bzoj4568: [Scoi2016]幸运数字
  6. PC端动态视频背景引导页(非自适应)
  7. css 弹性盒子200304
  8. 大数据预测实战-随机森林预测实战(三)-数据量对结果影响分析
  9. MyEclipse-6.5注冊码生成器源代码
  10. Oracle 存储方式大比拼
  11. 模块讲解----XML模块
  12. 三对角阵的一维数组表示
  13. mac文件管理服务器,Path Finder For Mac v8.6 高效的文件管理工具 _ 黑苹果乐园
  14. Tebleau-四象限图
  15. 记录spring编译过程遇到的问题previously initiated loading for a different type with name kotlin/sequences/Seque
  16. JAVA 实现图片原比例无损压缩
  17. JVM_虚拟机执行子系统
  18. IrfanView 看图软件下载及汉化
  19. 申请GOOGLE的企业邮局
  20. main函数带有参数

热门文章

  1. Adobe Camera Raw13 for mac(Raw增效工具)更新
  2. 【学习】一些有趣的数学分析题目
  3. PSO 粒子群优化算法 大整理
  4. 在启动Tomcat 6.0时发现第一条信息便是: The Apache Tomcat Native library which allows optimal performance in produc
  5. C语言进阶——likely和unlikely
  6. HBase统计表行数(RowCount)的四种方法
  7. 标量变量 c语言,标量变量
  8. OSM 的安装弱鸡随缘版
  9. 计算机网络:C/S和B/S两种模式
  10. 调伏自己的心,与自己和解