Quartz是一个完全由java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,它支持定时任务持久化到数据库,从而避免了重启服务器时任务丢失,支持分布式多节点,大大的提高了单节点定时任务的容错性。springboot在2.0版本以前没有对quartz做自动配置,因此需要我们自己去手动配置,网上找了许多资料,但是大都不能完全满足自己的需要,因此自己整合了一下方便以后参考(copy),整合代码基于springboot1.5.9和quartz2.3.0,过程如下:

  1、pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5.  
  6. <groupId>powerx.io</groupId>
  7. <artifactId>springboot-quartz</artifactId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. <packaging>jar</packaging>
  10.  
  11. <name>springboot-quartz</name>
  12. <description>Demo project for Spring Boot</description>
  13.  
  14. <parent>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-parent</artifactId>
  17. <version>1.5.9.RELEASE</version>
  18. <relativePath/> <!-- lookup parent from repository -->
  19. </parent>
  20.  
  21. <properties>
  22. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  23. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  24. <java.version>1.8</java.version>
  25. <druid.version>1.1.5</druid.version>
  26. <quartz.version>2.3.0</quartz.version>
  27. </properties>
  28.  
  29. <dependencies>
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-web</artifactId>
  33. </dependency>
  34.  
  35. <dependency>
  36. <groupId>mysql</groupId>
  37. <artifactId>mysql-connector-java</artifactId>
  38. <scope>runtime</scope>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-jdbc</artifactId>
  43. </dependency>
  44. <dependency>
  45. <groupId>com.alibaba</groupId>
  46. <artifactId>druid</artifactId>
  47. <version>${druid.version}</version>
  48. </dependency>
  49. <!--quartz相关依赖-->
  50. <dependency>
  51. <groupId>org.quartz-scheduler</groupId>
  52. <artifactId>quartz</artifactId>
  53. <version>${quartz.version}</version>
  54. </dependency>
  55. <dependency>
  56. <groupId>org.quartz-scheduler</groupId>
  57. <artifactId>quartz-jobs</artifactId>
  58. <version>${quartz.version}</version>
  59. </dependency>
  60. <!--定时任务需要依赖context模块-->
  61. <dependency>
  62. <groupId>org.springframework</groupId>
  63. <artifactId>spring-context-support</artifactId>
  64. </dependency>
  65. <dependency>
  66. <groupId>org.springframework.boot</groupId>
  67. <artifactId>spring-boot-starter-test</artifactId>
  68. <scope>test</scope>
  69. </dependency>
  70. </dependencies>
  71.  
  72. <build>
  73. <plugins>
  74. <plugin>
  75. <groupId>org.springframework.boot</groupId>
  76. <artifactId>spring-boot-maven-plugin</artifactId>
  77. </plugin>
  78. </plugins>
  79. </build>
  80.  
  81. </project>

  2、整合配置类

  采用jobDetail使用Spring Ioc托管方式来完成整合,我们可以在定时任务实例中使用Spring注入注解完成业务逻辑处理,代码如下

  1. package com.example.demo.config;
  2.  
  3. import org.quartz.spi.JobFactory;
  4. import org.quartz.spi.TriggerFiredBundle;
  5. import org.springframework.beans.factory.annotation.Autowire;
  6. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  7. import org.springframework.context.ApplicationContext;
  8. import org.springframework.context.ApplicationContextAware;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.core.io.ClassPathResource;
  12. import org.springframework.scheduling.annotation.EnableScheduling;
  13. import org.springframework.scheduling.quartz.SchedulerFactoryBean;
  14. import org.springframework.scheduling.quartz.SpringBeanJobFactory;
  15.  
  16. import javax.sql.DataSource;
  17.  
  18. @Configuration
  19. @EnableScheduling
  20. public class QuartzConfiguration {
  21. /**
  22. * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory
  23. * 实现任务实例化方式
  24. */
  25. public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
  26. ApplicationContextAware {
  27.  
  28. private transient AutowireCapableBeanFactory beanFactory;
  29.  
  30. @Override
  31. public void setApplicationContext(final ApplicationContext context) {
  32. beanFactory = context.getAutowireCapableBeanFactory();
  33. }
  34.  
  35. /**
  36. * 将job实例交给spring ioc托管
  37. * 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
  38. *
  39. * @param bundle
  40. * @return
  41. * @throws Exception
  42. */
  43. @Override
  44. protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
  45. final Object job = super.createJobInstance(bundle);
  46. /**
  47. * 将job实例交付给spring ioc
  48. */
  49. beanFactory.autowireBean(job);
  50. return job;
  51. }
  52. }
  53.  
  54. /**
  55. * 配置任务工厂实例
  56. *
  57. * @return
  58. */
  59. @Bean
  60. public JobFactory jobFactory() {
  61. /**
  62. * 采用自定义任务工厂 整合spring实例来完成构建任务*/
  63. AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
  64. return jobFactory;
  65. }
  66.  
  67. /**
  68. * 配置任务调度器
  69. * 使用项目数据源作为quartz数据源
  70. *
  71. * @param jobFactory 自定义配置任务工厂
  72. * @param dataSource 数据源实例
  73. * @return
  74. * @throws Exception
  75. */
  76. @Bean(destroyMethod = "destroy", autowire = Autowire.NO)
  77. public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception {
  78. SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
  79. //将spring管理job自定义工厂交由调度器维护
  80. schedulerFactoryBean.setJobFactory(jobFactory);
  81. //设置覆盖已存在的任务
  82. schedulerFactoryBean.setOverwriteExistingJobs(true);
  83. //项目启动完成后,等待2秒后开始执行调度器初始化
  84. schedulerFactoryBean.setStartupDelay(2);
  85. //设置调度器自动运行
  86. schedulerFactoryBean.setAutoStartup(true);
  87. //设置数据源,使用与项目统一数据源
  88. schedulerFactoryBean.setDataSource(dataSource);
  89. //设置上下文spring bean name
  90. schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
  91. //设置配置文件位置
  92. schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
  93. return schedulerFactoryBean;
  94. }
  95. }

  AutowiringSpringBeanJobFactory:可以看到上面配置类中,AutowiringSpringBeanJobFactory我们继承了SpringBeanJobFactory类,并且通过实现ApplicationContextAware接口获取ApplicationContext设置方法,通过外部实例化时设置ApplicationContext实例对象,在createJobInstance方法内,我们采用AutowireCapableBeanFactory来托管SpringBeanJobFactory类中createJobInstance方法返回的定时任务实例,这样我们就可以在定时任务类内使用Spring Ioc相关的注解进行注入业务逻辑实例了。

  JobFactory:自定义任务工厂

  SchedulerFactoryBean:使用项目内部数据源的方式来设置调度器的jobSotre,官方quartz有两种持久化的配置方案。

  第一种:采用quartz.properties配置文件配置独立的定时任务数据源,可以与使用项目的数据库完全独立。
  第二种:采用与创建项目统一个数据源,定时任务持久化相关的表与业务逻辑在同一个数据库内。

  可以根据实际的项目需求采取不同的方案,我采用了第二种方案,在上面配置类中可以看到方法schedulerFactoryBean内自动注入了JobFactory实例,也就是我们自定义的AutowiringSpringBeanJobFactory任务工厂实例,另外一个参数就是DataSource,在我们引入spring-boot-starter-jdbc依赖后会根据application.yml文件内的数据源相关配置自动实例化DataSource实例,这里直接注入是没有问题的。我们通过调用SchedulerFactoryBean对象的setConfigLocation方法来设置quartz定时任务框架的基本配置,配置文件所在位置:resources/quartz.properties => classpath:/quartz.properties下。

  quartz.properties内容如下:

  1. org.quartz.scheduler.instanceName = schedulerFactoryBean
  2.  
  3. org.quartz.scheduler.instanceId = AUTO
  4.  
  5. org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
  6.  
  7. org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
  8.  
  9. org.quartz.jobStore.tablePrefix = QRTZ_
  10.  
  11. org.quartz.jobStore.useProperties = false
  12.  
  13. org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
  14.  
  15. org.quartz.threadPool.threadCount = 10
  16.  
  17. org.quartz.threadPool.threadPriority = 5

  在上面配置中org.quartz.jobStore.classorg.quartz.jobStore.driverDelegateClass是定时任务持久化的关键配置,配置了数据库持久化定时任务以及采用MySQL数据库进行连接,当然你也可以连接别的数据库org.quartz.jobStore.tablePrefix属性配置了定时任务数据表的前缀,在quartz官方提供的创建表SQL脚本默认就是qrtz_,我们需要解压quartz2.3.0的jar,在quartz-2.2.3/docs/dbTables下找到tables_mysql_innodb.sql,然后在mysql客户端执行来创建相应的表。

  3、动态定时任务demo

  QuartzService.java

  1. package com.example.demo.service;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8.  
  9. import javax.annotation.PostConstruct;
  10.  
  11. import org.quartz.CronScheduleBuilder;
  12. import org.quartz.CronTrigger;
  13. import org.quartz.DateBuilder;
  14. import org.quartz.DateBuilder.IntervalUnit;
  15. import org.quartz.JobBuilder;
  16. import org.quartz.JobDetail;
  17. import org.quartz.JobExecutionContext;
  18. import org.quartz.JobKey;
  19. import org.quartz.Scheduler;
  20. import org.quartz.SchedulerException;
  21. import org.quartz.SimpleScheduleBuilder;
  22. import org.quartz.Trigger;
  23. import org.quartz.TriggerBuilder;
  24. import org.quartz.TriggerKey;
  25. import org.quartz.impl.matchers.GroupMatcher;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.scheduling.quartz.QuartzJobBean;
  28. import org.springframework.stereotype.Service;
  29.  
  30. @Service
  31. public class QuartzService {
  32.  
  33. @Autowired
  34. private Scheduler scheduler;
  35.  
  36. @PostConstruct
  37. public void startScheduler() {
  38. try {
  39. scheduler.start();
  40. } catch (SchedulerException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44.  
  45. /**
  46. * 增加一个job
  47. *
  48. * @param jobClass
  49. * 任务实现类
  50. * @param jobName
  51. * 任务名称
  52. * @param jobGroupName
  53. * 任务组名
  54. * @param jobTime
  55. * 时间表达式 (这是每隔多少秒为一次任务)
  56. * @param jobTimes
  57. * 运行的次数 (<0:表示不限次数)
  58. */
  59. public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
  60. int jobTimes) {
  61. try {
  62. JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
  63. .build();
  64. // 使用simpleTrigger规则
  65. Trigger trigger = null;
  66. if (jobTimes < 0) {
  67. trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
  68. .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
  69. .startNow().build();
  70. } else {
  71. trigger = TriggerBuilder
  72. .newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
  73. .repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
  74. .startNow().build();
  75. }
  76. scheduler.scheduleJob(jobDetail, trigger);
  77. } catch (SchedulerException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81.  
  82. /**
  83. * 增加一个job
  84. *
  85. * @param jobClass
  86. * 任务实现类
  87. * @param jobName
  88. * 任务名称
  89. * @param jobGroupName
  90. * 任务组名
  91. * @param jobTime
  92. * 时间表达式 (如:0/5 * * * * ? )
  93. */
  94. public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime) {
  95. try {
  96. // 创建jobDetail实例,绑定Job实现类
  97. // 指明job的名称,所在组的名称,以及绑定job类
  98. JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
  99. .build();
  100. // 定义调度触发规则
  101. // 使用cornTrigger规则
  102. Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)// 触发器key
  103. .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
  104. .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();
  105. // 把作业和触发器注册到任务调度中
  106. scheduler.scheduleJob(jobDetail, trigger);
  107. } catch (Exception e) {
  108. e.printStackTrace();
  109. }
  110. }
  111.  
  112. /**
  113. * 修改 一个job的 时间表达式
  114. *
  115. * @param jobName
  116. * @param jobGroupName
  117. * @param jobTime
  118. */
  119. public void updateJob(String jobName, String jobGroupName, String jobTime) {
  120. try {
  121. TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
  122. CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  123. trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
  124. .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
  125. // 重启触发器
  126. scheduler.rescheduleJob(triggerKey, trigger);
  127. } catch (SchedulerException e) {
  128. e.printStackTrace();
  129. }
  130. }
  131.  
  132. /**
  133. * 删除任务一个job
  134. *
  135. * @param jobName
  136. * 任务名称
  137. * @param jobGroupName
  138. * 任务组名
  139. */
  140. public void deleteJob(String jobName, String jobGroupName) {
  141. try {
  142. scheduler.deleteJob(new JobKey(jobName, jobGroupName));
  143. } catch (Exception e) {
  144. e.printStackTrace();
  145. }
  146. }
  147.  
  148. /**
  149. * 暂停一个job
  150. *
  151. * @param jobName
  152. * @param jobGroupName
  153. */
  154. public void pauseJob(String jobName, String jobGroupName) {
  155. try {
  156. JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
  157. scheduler.pauseJob(jobKey);
  158. } catch (SchedulerException e) {
  159. e.printStackTrace();
  160. }
  161. }
  162.  
  163. /**
  164. * 恢复一个job
  165. *
  166. * @param jobName
  167. * @param jobGroupName
  168. */
  169. public void resumeJob(String jobName, String jobGroupName) {
  170. try {
  171. JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
  172. scheduler.resumeJob(jobKey);
  173. } catch (SchedulerException e) {
  174. e.printStackTrace();
  175. }
  176. }
  177.  
  178. /**
  179. * 立即执行一个job
  180. *
  181. * @param jobName
  182. * @param jobGroupName
  183. */
  184. public void runAJobNow(String jobName, String jobGroupName) {
  185. try {
  186. JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
  187. scheduler.triggerJob(jobKey);
  188. } catch (SchedulerException e) {
  189. e.printStackTrace();
  190. }
  191. }
  192.  
  193. /**
  194. * 获取所有计划中的任务列表
  195. *
  196. * @return
  197. */
  198. public List<Map<String, Object>> queryAllJob() {
  199. List<Map<String, Object>> jobList = null;
  200. try {
  201. GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
  202. Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
  203. jobList = new ArrayList<Map<String, Object>>();
  204. for (JobKey jobKey : jobKeys) {
  205. List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
  206. for (Trigger trigger : triggers) {
  207. Map<String, Object> map = new HashMap<>();
  208. map.put("jobName", jobKey.getName());
  209. map.put("jobGroupName", jobKey.getGroup());
  210. map.put("description", "触发器:" + trigger.getKey());
  211. Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
  212. map.put("jobStatus", triggerState.name());
  213. if (trigger instanceof CronTrigger) {
  214. CronTrigger cronTrigger = (CronTrigger) trigger;
  215. String cronExpression = cronTrigger.getCronExpression();
  216. map.put("jobTime", cronExpression);
  217. }
  218. jobList.add(map);
  219. }
  220. }
  221. } catch (SchedulerException e) {
  222. e.printStackTrace();
  223. }
  224. return jobList;
  225. }
  226.  
  227. /**
  228. * 获取所有正在运行的job
  229. *
  230. * @return
  231. */
  232. public List<Map<String, Object>> queryRunJob() {
  233. List<Map<String, Object>> jobList = null;
  234. try {
  235. List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
  236. jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
  237. for (JobExecutionContext executingJob : executingJobs) {
  238. Map<String, Object> map = new HashMap<String, Object>();
  239. JobDetail jobDetail = executingJob.getJobDetail();
  240. JobKey jobKey = jobDetail.getKey();
  241. Trigger trigger = executingJob.getTrigger();
  242. map.put("jobName", jobKey.getName());
  243. map.put("jobGroupName", jobKey.getGroup());
  244. map.put("description", "触发器:" + trigger.getKey());
  245. Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
  246. map.put("jobStatus", triggerState.name());
  247. if (trigger instanceof CronTrigger) {
  248. CronTrigger cronTrigger = (CronTrigger) trigger;
  249. String cronExpression = cronTrigger.getCronExpression();
  250. map.put("jobTime", cronExpression);
  251. }
  252. jobList.add(map);
  253. }
  254. } catch (SchedulerException e) {
  255. e.printStackTrace();
  256. }
  257. return jobList;
  258. }
  259.  
  260. }

  UserService.java

  1. package com.example.demo.service;
  2.  
  3. import org.springframework.stereotype.Service;
  4.  
  5. @Service
  6. public class UserService {
  7.  
  8. public void play() {
  9. System.out.println("user id play");
  10. }
  11.  
  12. public void study() {
  13. System.out.println("user id study");
  14. }
  15. }

  TestJob1.java

  1. package com.example.demo.job;
  2.  
  3. import java.util.Date;
  4.  
  5. import org.quartz.JobExecutionContext;
  6. import org.quartz.JobExecutionException;
  7. import org.springframework.scheduling.quartz.QuartzJobBean;
  8.  
  9. public class TestJob1 extends QuartzJobBean {
  10.  
  11. @Override
  12. protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
  13.  
  14. System.out.println(new Date() + " job执行");
  15. }
  16.  
  17. }

  TestJob2.java

  1. package com.example.demo.job;
  2.  
  3. import java.util.Date;
  4.  
  5. import org.quartz.JobExecutionContext;
  6. import org.quartz.JobExecutionException;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.scheduling.quartz.QuartzJobBean;
  9. import org.springframework.stereotype.Component;
  10.  
  11. import com.example.demo.service.UserService;
  12. @Component
  13. public class TestJob2 extends QuartzJobBean {
  14.  
  15. //注入业务service,完成定时任务逻辑
  16. @Autowired
  17. private UserService service;
  18. @Override
  19. protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
  20. System.out.println(new Date() + " job2执行");
  21. service.play();
  22. }
  23.  
  24. }

  TestController.java

  1. package com.example.demo.controller;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6.  
  7. import com.example.demo.job.TestJob1;
  8. import com.example.demo.job.TestJob2;
  9. import com.example.demo.service.QuartzService;
  10.  
  11. @RestController
  12. public class TestController {
  13.  
  14. @Autowired
  15. private QuartzService quartzService;
  16. @RequestMapping("/addjob")
  17. public void startJob(String type) {
  18. if("TestJob1".equals(type)) {
  19. quartzService.addJob(TestJob1.class, "job1", "test", "0/5 * * * * ?");
  20.  
  21. }else {
  22. quartzService.addJob(TestJob2.class, "job2", "test", "0/5 * * * * ?");
  23. }
  24. }
  25.  
  26. @RequestMapping("/updatejob")
  27. public void updatejob() {
  28. quartzService.updateJob("job1", "test", "0/10 * * * * ?");
  29. }
  30.  
  31. @RequestMapping("/deletejob")
  32. public void deletejob() {
  33. quartzService.deleteJob("job1", "test");
  34. }
  35.  
  36. @RequestMapping("/pauseJob")
  37. public void pauseJob() {
  38. quartzService.pauseJob("job1", "test");
  39. }
  40.  
  41. @RequestMapping("/resumeJob")
  42. public void resumeJob() {
  43. quartzService.resumeJob("job1", "test");
  44. }
  45.  
  46. @RequestMapping("/queryAllJob")
  47. public Object queryAllJob() {
  48. return quartzService.queryAllJob();
  49. }
  50.  
  51. @RequestMapping("/queryRunJob")
  52. public Object queryRunJob() {
  53. return quartzService.queryRunJob();
  54. }
  55. }

  4、application.yml

  1. spring:
  2. datasource:
  3. type: com.alibaba.druid.pool.DruidDataSource
  4. driver-class-name: com.mysql.jdbc.Driver
  5. url: jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
  6. username: root
  7. password: root
  8. jpa:
  9. hibernate:
  10. ddl-auto: update #ddl-auto:设为update表示每次都不会重新建表
  11. show-sql: true
  12. application:
  13. name: quartz-cluster-node-first
  14. server:
  15. port: 8081
  16. # 打印日志
  17. logging:
  18. level:
  19. root: INFO
  20. org.hibernate: INFO
  21. org.hibernate.type.descriptor.sql.BasicBinder: TRACE
  22. org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
  23. com.springms: DEBUG

  至此,springboot整合quartz实现动态定时任务和任务持久化完毕,各功能我都测试过,符合预期,具体结果不再贴出,小伙伴们在使用时要注意springboot和quartz的版本问题,很多时候并不是代码有问题,而是jar不匹配。springboot2.0以后,直接有了spring-boot-starter-quartz包,我们只需要把原来的jar替换掉,无需任何配置就完成了整合。

springboot和quartz整合实现动态定时任务(持久化单节点)的更多相关文章

  1. 在springBoot与quartz 整合中 @Transaction 失效

    问题1::springBoot在与quartz 整合时,使用@Transaction 注解时事务失效 解决方案:创建一个类使用@component被spring管理 ,使用@Transaction标识 ...

  2. quartz spring 实现动态定时任务

    在实际项目应用中经常会用到定时任务,可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间.频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quar ...

  3. springboot和quartz整合分布式多节点

    虽然单个Quartz实例能给予我们很好的任务job调度能力,但它不能满足典型的企业需求,如可伸缩性.高可靠性满足.假如你需要故障转移的能力并能运行日益增多的 Job,Quartz集群势必成为你应用的一 ...

  4. Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置

    Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置 >>>>>>>>>>>>&g ...

  5. spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】

    最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要 ...

  6. Spring 整合 Quartz 实现动态定时任务

    复制自:https://www.2cto.com/kf/201605/504659.html 最近项目中需要用到定时任务的功能,虽然Spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能 ...

  7. 【转】Spring 整合 Quartz 实现动态定时任务

    http://blog.csdn.net/u014723529/article/details/51291289 最近项目中需要用到定时任务的功能,虽然spring 也自带了一个轻量级的定时任务实现, ...

  8. Spring 整合 Quartz 实现动态定时任务(附demo)

    最近项目中需要用到定时任务的功能,虽然Spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 普通定时任务 首先 ...

  9. spring与quartz整合实现分布式动态创建,删除,改变执行时间定时任务(mysql数据库)

    背景:因为在项目中用到了定时任务,当时想到了spring的quartz,写完发现费了很大功夫,光是整合就花了一上午,其中最大的问题就是版本问题,项目中用的是spring3.2.8的版本,查阅发现,3. ...

随机推荐

  1. How do I avoid capturing self in blocks when implementing an API?

    Short answer Instead of accessing self directly, you should access it indirectly, from a reference t ...

  2. struts2的validate输入验证

    原创 struts2的输入验证有两种方式: 使用validate()方法实现验证 使用验证文件实现验证 下面通过一个例子介绍validate()方法验证——实现客户注册输入验证 设计的JSP页面代码: ...

  3. java学习(七)java中抽象类及 接口

    抽象类的特点: A:抽象类和抽象方法必须用abstract关键字修饰. B:抽象类中不一定有抽象方法,但是抽象方法的类必须定义为抽象类 c: 抽象类不能被实例化,因为它不是具体的. 抽象类有构造方法, ...

  4. Partition--分区切换

    现有数据表[dbo].[staging_TB1_20131018-104722]和分区表[dbo].[TB1],需要将分区表和数据表中做数据交换 CREATE TABLE [dbo].[staging ...

  5. [HTTP]Nonocast.http post方法

    Nonocast.Http is a free, open source developer focused web service via http for small and medium sof ...

  6. asp.net mvc项目创建WebApi简单例子

    1.创建默认路由的映射. namespace RedisDemo.App_Start { public class WebApiConfig { public static void Register ...

  7. loadrunner 11问题汇总

    1.问题描述:安装loadrunner11后,录制脚本时,explore未打开,event为0,录制结果为空.安装环境是window7+ie8+loadrunner11 解决方案: 1.首先要把ie设 ...

  8. Excel一对多查询(index+small+if)

    一.学习 一对多查询模式化数组公式: =INDEX(区域,SMALL(IF(条件,行号数组,4^8),ROW(A1))) 三键齐按(ctrl+shift+回车) 在具有多个符合条件的情况下,提取和匹配 ...

  9. python 小点

    python中列表不能除以列表,列表不能除以整数.浮点数. numpy数组可以实现数组除以整数.

  10. php面向对象编程_1

    1, php面向对象编程的三大特征: (1) 封装性,封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法)才能对数据进行操作. (2) 继承 ...