SpringBoot:工厂模式实现定时任务可配置
pringBoot:工厂模式实现定时任务可配置
需要:使用springboot,实现定时任务可配置。
定时任务可在代码中写死,在配置文件中配置,这些都不能实现定时任务在服务器不重启的情况下可配置。
为实现需求,使定时任务在时间表达式或者定时任务类更改时,实现定时任务的重新设置并启动。
pom包配置
复制代码
org.springframework.boot
spring-boot-starter-web
1.5.8.RELEASE
org.springframework.boot
spring-boot-starter
1.5.8.RELEASE
org.springframework.boot
spring-boot-starter-test
1.5.8.RELEASE
test
org.springframework.boot
spring-boot-devtools
1.5.8.RELEASE
true
org.springframework.boot
spring-boot-starter-data-jpa
1.5.8.RELEASE
mysql
mysql-connector-java
5.1.44
复制代码
项目采用springboot框架1.5.8版本,未采用quartz框架,使用spring-boot-devtools包springboot自带的定时任务完成。
因为spring2.0版本下尚未集成quartz,根据需求采用这种模式。
2.配置文件
复制代码
jpa
spring.jpa.generate-ddl: false
spring.jpa.show-sql: true
spring.jpa.hibernate.ddl-auto: none
spring.jpa.properties.hibernate.format_sql: false
DataSource配置
spring.datasource.url=${pom.datasource.url}
spring.datasource.username=${pom.datasource.username}
spring.datasource.password=${pom.datasource.password}
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
复制代码
3.application启动项
复制代码
1 @ComponentScan(basePackages = { "com.deleba.quartz" })
2 @SpringBootApplication
3 @EnableScheduling
4 public class QuartzApplication {
5
6 public static void main(String[] args) {
7 SpringApplication app = new SpringApplication(MCloudQuartzApplication.class);
8 app.addListeners(new StartApplicationListener());
9 app.run(args);
10 }
11
12 @Bean("sessionFactory")
13 public HibernateJpaSessionFactoryBean sessionFactory() {
14 return new HibernateJpaSessionFactoryBean();
15 }
16
17 @Bean
18 public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
19 return new ThreadPoolTaskScheduler();
20 }
21 }
复制代码
4.定时任务实体
复制代码
1 package com.deleba.quartz.entity;
2
3 import java.io.Serializable;
4 import java.util.Date;
5
6 import javax.persistence.Entity;
7 import javax.persistence.GeneratedValue;
8 import javax.persistence.GenerationType;
9 import javax.persistence.Id;
10 import javax.persistence.Table;
11
12 @Entity
13 @Table(name = "quartz_cron")
14 public class CronVO implements Serializable {
15
16 private static final long serialVersionUID = -3406421161273529348L;
17 @Id
18 @GeneratedValue(strategy = GenerationType.AUTO)
19 private Integer cronId;
20 /**
21 * cron
22 */
23 private String cron;
24 /**
25 * 定时任务名称
26 */
27 private String quartzName;
28 /**
29 * 状态("1":有效 "0":无效)
30 */
31 private Integer status;
32 /**
33 * 定时任务类
34 */
35 private String schedulerClass;
36 /**
37 * 时间戳
38 */
39 private Date ts;
40
41 public CronVO() {
42 }
43
44 public Date getTs() {
45 return ts;
46 }
47
48 public void setTs(Date ts) {
49 this.ts = ts;
50 }
51
52 public String getSchedulerClass() {
53 return schedulerClass;
54 }
55
56 public void setSchedulerClass(String schedulerClass) {
57 this.schedulerClass = schedulerClass;
58 }
59
60 public String getQuartzName() {
61 return quartzName;
62 }
63
64 public void setQuartzName(String quartzName) {
65 this.quartzName = quartzName;
66 }
67
68 public Integer getCronId() {
69 return cronId;
70 }
71
72 public void setCronId(Integer cronId) {
73 this.cronId = cronId;
74 }
75
76 public String getCron() {
77 return cron;
78 }
79
80 public void setCron(String cron) {
81 this.cron = cron;
82 }
83
84 public Integer getStatus() {
85 return status;
86 }
87
88 public void setStatus(Integer status) {
89 this.status = status;
90 }
91
92 }
复制代码
5.定时任务trigger
复制代码
1 package com.deleba.quartz.trigger;
2
3 import java.util.Date;
4
5 import org.apache.commons.lang3.StringUtils;
6 import org.springframework.scheduling.Trigger;
7 import org.springframework.scheduling.TriggerContext;
8 import org.springframework.scheduling.support.CronTrigger;
9
10 /**
11 * 定时任务trigger
12 *
13 * @author Administrator
14
15 /
16 public class QuartzTrigger implements Trigger {
17
18 private String cron;
19
20 public McloudTrigger(String cron) {
21 super();
22 this.cron = cron;
23 }
24
25 @Override
26 public Date nextExecutionTime(TriggerContext triggerContext) {
27 if (StringUtils.isBlank(cron)) {
28 return null;
29 }
30 // 定时任务触发,可修改定时任务的执行周期
31 CronTrigger trigger = new CronTrigger(cron);
32 Date nextExecDate = trigger.nextExecutionTime(triggerContext);
33 return nextExecDate;
34 }
35
36 }
复制代码
6.定时任务线程
复制代码
1 package com.deleba.quartz.thread;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 import com.deleba.quartz.service.ILicenseCarrierService;
7 import com.deleba.quartz.utils.SpringUtil;
8
9 /**
10 * 定时任务线程
11 *
12 * @author Administrator
13
14 /
15 public class QuartzThread implements Runnable {
16
17 private Logger logger = LoggerFactory.getLogger(QuartzThread.class);
18
19 @Override
20 public void run() {
21 try {
22 //获取bean
23 IDemoService licenseCarrierService = SpringUtil.getBean(IDemoService.class);
24 //执行任务
25 lDemoService.method();
26 logger.info("执行成功");
27 } catch (Exception e) {
28 logger.error("执行失败: " + e.getLocalizedMessage());
29 }
30 }
31
32 }
复制代码
由此定时任务线程,没在注入springbean,使用@Autowired获取不到bean,需要写一个获取bean的util来获取springbean
复制代码
1 package com.deleba.quartz.utils;
2
3 import org.springframework.beans.BeansException;
4 import org.springframework.context.ApplicationContext;
5 import org.springframework.context.ApplicationContextAware;
6 import org.springframework.stereotype.Component;
7
8 /**
9 * 获取bean工具
10 *
11 * @author Administrator
12
13 /
14 @Component
15 public class SpringUtil implements ApplicationContextAware {
16
17 private static ApplicationContext applicationContext;
18
19 @Override
20 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
21 if (SpringUtil.applicationContext == null) {
22 SpringUtil.applicationContext = applicationContext;
23 }
24 }
25
26 // 获取applicationContext
27 public static ApplicationContext getApplicationContext() {
28 return applicationContext;
29 }
30
31 // 通过name获取 Bean.
32 public static Object getBean(String name) {
33 return getApplicationContext().getBean(name);
34 }
35
36 // 通过class获取Bean.
37 public static T getBean(Class clazz) {
38 return getApplicationContext().getBean(clazz);
39 }
40
41 // 通过name,以及Clazz返回指定的Bean
42 public static T getBean(String name, Class clazz) {
43 return getApplicationContext().getBean(name, clazz);
44 }
45
46 }
复制代码
7.定时任务类
复制代码
1 package com.deleba.quartz.scheduler;
2
3 import java.util.concurrent.ScheduledFuture;
4
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
8
9 import com.deleba.quartz.trigger.quratzrigger;
10
11 /
12 * 定时任务
13 *
14 * @author Administrator
15
16 /
17 public class QuartzScheduler {
18
19 private Logger logger = LoggerFactory.getLogger(QuartzScheduler.class);
20
21 private ThreadPoolTaskScheduler threadPoolTaskScheduler;
22
23 private ScheduledFuture<?> scheduledFuture;
24
25 private String cron = "";//事件表达式
26
27 private Runnable runnable;//定时任务
28
29 public McloudScheduler(Runnable runnable, String cron, ThreadPoolTaskScheduler threadPoolTaskScheduler) {
30 super();
31 this.runnable = runnable;
32 this.cron = cron;
33 this.threadPoolTaskScheduler = threadPoolTaskScheduler;
34 }
35
36 public String getCron() {
37 return cron;
38 }
39
40 /
41 * 停止定时任务
42 */
43 public void stop() {
44 if (scheduledFuture != null) {
45 scheduledFuture.cancel(true);
46 }
47 }
48
49 /**
50 * 设置时间表达式
51 *
52 * @param cron
53 */
54 public void setCron(String cron) {
55 this.cron = cron;
56 stop();
57 scheduledFuture = threadPoolTaskScheduler.schedule(runnable, new McloudTrigger(cron));
58 }
59 }
复制代码
8.定时任务工厂类
复制代码
1 package com.deleba.quartz.factory;
2
3 import java.util.HashMap;
4
5 import java.util.Map;
6
7 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
8
9 import com.deleba.quartz.scheduler.QuzrtzScheduler;
10
11 /
12 * 定时任务工厂类
13 *
14 * @author Administrator
15
16 /
17 public class ScheduledFutureFactory {
18
19 private static Map<Integer, QuartzScheduler> map = new HashMap<>(0);
20
21 /
22 * 获取定时任务实例
23 *
24 * @param cronId
25 * @param runnable
26 * @param cron
27 * @param threadPoolTaskScheduler
28 * @return
29 */
30 public static QuartzScheduler createQuartzScheduler(Integer cronId, Runnable runnable, String cron,
31 ThreadPoolTaskScheduler threadPoolTaskScheduler) {
32 QuartzScheduler quartzScheduler = new QuartzScheduler(runnable, cron, threadPoolTaskScheduler);
33 map.put(cronId, quartzScheduler);
34 return quartzScheduler;
35 }
36
37 /**
38 * 根据key获取定时任务实例
39 *
40 * @param cronId
41 * @return
42 */
43 public static QuartzScheduler getQuartzScheduler(Integer cronId) {
44 return map.get(cronId);
45 }
46
47 }
复制代码
9.controller
复制代码
1 package com.deleba.quartz.controller;
2
3 import java.util.List;
4
5 import org.apache.commons.lang3.StringUtils;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
10 import org.springframework.web.bind.annotation.RequestBody;
11 import org.springframework.web.bind.annotation.RequestMapping;
12 import org.springframework.web.bind.annotation.RequestMethod;
13 import org.springframework.web.bind.annotation.RequestParam;
14 import org.springframework.web.bind.annotation.ResponseBody;
15 import org.springframework.web.bind.annotation.RestController;
16
17 import com.deleba.quartz.common.response.JsonResponse;
18 import com.deleba.quartz.common.response.JsonResponseBuilder;
19 import com.deleba.quartz.entity.CronVO;
20 import com.deleba.quartz.factory.ScheduledFutureFactory;
21 import com.deleba.quartz.scheduler.QuartzScheduler;
22 import com.deleba.quartz.service.ICronService;
23
24 /
25 定时任务操作--表现层
26 *
27 * @author Administrator
28
29 /
30 @RestController
31 @RequestMapping("/scheduler")
32 public class SchedulerController {
33
34 private Logger logger = LoggerFactory.getLogger(SchedulerController.class);
35
36 @Autowired
37 private ICronService cronService;
38
39 @Autowired
40 private ThreadPoolTaskScheduler threadPoolTaskScheduler;
41
42 /
43 * 开启定时任务
44 *
45 * @param cronId
46 * @return
47 /
48 @RequestMapping(value = "/start", method = RequestMethod.GET)
49 @ResponseBody
50 public JsonResponse start(@RequestParam(name = "cronId", defaultValue = "") Integer cronId) {
51 // 1.参数校验
52 CronVO cronVO = cronService.findByCronId(cronId);
53 if (cronVO == null) {
54 return JsonResponseBuilder.buildFailResponse("cronId无效");
55 }
56 String cron = cronVO.getCron();
57 String schedulerClass = cronVO.getSchedulerClass();
58 // 2.开启任务
59 try {
60 Runnable runnable = (Runnable) Class.forName(schedulerClass).newInstance();
61 QuartzScheduler quartzScheduler = ScheduledFutureFactory.getQuartzScheduler(cronId);
62 if (quartzScheduler == null) {
63 quartzScheduler = ScheduledFutureFactory.createQuartzScheduler(cronId, runnable, cron,
64 threadPoolTaskScheduler);
65 }
66 quartzScheduler.setCron(cron);
67 cronVO.setStatus(1);
68 cronService.update(cronVO);
69 logger.info("开启定时任务成功");
70 return JsonResponseBuilder.buildSuccessResponse("开启定时任务成功");
71 } catch (Exception e) {
72 logger.error(e.getMessage(), e);
73 return JsonResponseBuilder.buildFailResponse("开启定时任务失败");
74 }
75 }
76
77 /
78 * 关闭定时任务
79 *
80 * @param cronId
81 * @return
82 /
83 @RequestMapping(value = "/close", method = RequestMethod.GET)
84 @ResponseBody
85 public JsonResponse close(@RequestParam(name = "cronId", defaultValue = "") Integer cronId) {
86 // 1.参数校验
87 CronVO cronVO = cronService.findByCronId(cronId);
88 if (cronVO == null) {
89 return JsonResponseBuilder.buildFailResponse("cronId无效");
90 }
91 String cron = cronVO.getCron();
92 String schedulerClass = cronVO.getSchedulerClass();
93 // 2.关闭任务
94 try {
95 Runnable runnable = (Runnable) Class.forName(schedulerClass).newInstance();
96 QuartzScheduler quartzScheduler = ScheduledFutureFactory.getQuartzScheduler(cronId);
97 if (mcloudScheduler == null) {
98 quartzScheduler = ScheduledFutureFactory.createQuartzScheduler(cronId, runnable, cron,
99 threadPoolTaskScheduler);
100 }
101 quartzScheduler.stop();
102 cronVO.setStatus(0);
103 cronService.update(cronVO);
104 logger.info("关闭定时任务成功");
105 return JsonResponseBuilder.buildSuccessResponse("关闭定时任务成功");
106 } catch (Exception e) {
107 logger.error(e.getMessage(), e);
108 return JsonResponseBuilder.buildFailResponse("关闭定时任务失败");
109 }
110 }
111
112 /
113 更新定时任务
114 *
115 * @param cronVO
116 * @return
117 /
118 @RequestMapping(value = "/update", method = RequestMethod.POST)
119 @ResponseBody
120 public JsonResponse update(@RequestBody CronVO cronVO) {
121 // 1.参数校验
122 Integer cronId = cronVO.getCronId();
123 String cron = cronVO.getCron();
124 Integer status = cronVO.getStatus();
125 String schedulerClass = cronVO.getSchedulerClass();
126 if (StringUtils.isBlank(cron) || StringUtils.isBlank(schedulerClass)) {
127 return JsonResponseBuilder.buildFailResponse("时间表达式和定时任务类不可为空");
128 }
129 try {
130 // 2.更新实体,定时任务开启状态则重新设置表达式
131 cronService.update(cronVO);
132 if (status == 1) {
133 Runnable runnable = (Runnable) Class.forName(schedulerClass).newInstance();
134 QuartzScheduler quartzScheduler = ScheduledFutureFactory.getQuartzScheduler(cronId);
135 if (mcloudScheduler == null) {
136 mcloudScheduler = ScheduledFutureFactory.createQuartzScheduler(cronId, runnable, cron,
137 threadPoolTaskScheduler);
138 }
139 mcloudScheduler.setCron(cron);
140 }
141 } catch (Exception e) {
142 logger.error(e.getMessage(), e);
143 return JsonResponseBuilder.buildFailResponse("更新定时任务失败");
144 }
145 logger.info("更新定时任务成功");
146 return JsonResponseBuilder.buildFailResponse("更新定时任务成功");
147 }
148
149 /
150 * 根据主键获取定时任务相关信息
151 *
152 * @param cronId
153 * @return
154 /
155 @RequestMapping(value = "/findById", method = RequestMethod.GET)
156 @ResponseBody
157 public CronVO findById(@RequestParam(name = "cronId", defaultValue = "") Integer cronId) {
158 if (cronId == null) {
159 return null;
160 }
161 CronVO cronVO = cronService.findByCronId(cronId);
162 return cronVO;
163 }
164
165 /
166 * 获取所有定时任务信息
167 *
168 * @return
169 */
170 @RequestMapping(value = "/findAll", method = RequestMethod.GET)
171 @ResponseBody
172 public List findAll() {
173 return cronService.findAll();
174 }
SpringBoot:工厂模式实现定时任务可配置的更多相关文章
- Springboot中实现策略模式+工厂模式
策略模式和工厂模式相信大家都比较熟悉,但是大家有没有在springboot中实现策略和工厂模式? 具体策略模式和工厂模式的UML我就不给出来了,使用这个这两个模式主要是防止程序中出现大量的IF ELS ...
- 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式
1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...
- springboot中使用自定义注解实现策略模式,去除工厂模式的switch或ifelse,实现新增策略代码零修改
前言 思路与模拟业务 源码地址 https://gitee.com/houzheng1216/springboot 整体思路就是通过注解在策略类上指定约定好的type,项目启动之后将所有有注解的typ ...
- SpringBoot使用策略模式+工厂模式
为了防止大量的if...else...或switch case代码的出现,可以使用策略模式+工厂模式进行优化. 在我的项目当中,报表繁多,所以尝试了这种方式进行优化报表的架构.代码很简单,如下: Fa ...
- spring.factories配置文件的工厂模式
在springboot的各个依赖包下,我们经常看到META-INF/spring.factories这个文件.spring.factories文件的内容基本上都是这样的格式: # Initialize ...
- PHP 面向对象编程和设计模式 (3/5) - 单例模式和工厂模式
PHP高级程序设计 学习笔记 2014.06.11 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...
- 从接口、抽象类到工厂模式再到JVM来总结一些问题
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习! 涉及到的知识点总结如下: 为什么使用接口? 接口和抽象类的区别 简单工厂模式总结 Java中new和newInstance的区别 J ...
- php设计模式总结-工厂模式
使用工厂模式的目的或目标? 工厂模式的最大优点在于创建对象上面,就是把创建对象的过程封装起来,这样随时可以产生一个新的对象.减少代码进行复制粘帖,耦合关系重,牵一发动其他部分代码. 通俗的说,以前创建 ...
- Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...
随机推荐
- CGAL 4.6 - Surface Reconstruction from Point Sets
http://doc.cgal.org/latest/Surface_reconstruction_points_3/ The following example reads a point set, ...
- 11java基础继承
一. 继承相关 18.实现如下类之间的继承关系,并编写Music类来测试这些类. package com.hry.test; public class Instrument { ...
- window.location.href 跳转无历史记录
需求:从页面a单点登录跳至页面b,在页面b里做判断符合条件后location.href至c页面 问题:在页面c中点击返回按钮页面回到了a,正常情况下应该回到页面b 原因:在当前页面的 onload 事 ...
- [USACO11OPEN]奶牛跳棋Cow Checkers(博弈论)
题目描述 One day, Bessie decides to challenge Farmer John to a game of 'Cow Checkers'. The game is playe ...
- 增删改查 报异常org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readO
可能是Spring配置文件 事务通知里面的方法 与实际方法不匹配 <tx:advice id="advice" transaction-manager="tran ...
- JavaScript--文本框中只允许输入数字的操作(其他字符不显示)
在web网页中,尤其是某些提交表单操作,需要验证文本框输入内容,本文利用文本框键盘事件和事件对象,对文本框只允许输入数字方法进行总结. 1.键盘事件 keydown ---->键盘按下事件 ...
- XPath Helper的安装使用
XPath Helper的安装使用 xpath helper 是一款chrome浏览器插件,主要用来分析当前网页信息的xpath,在抓取数据时一般会使用到xpath. 安装 下载地址:http://c ...
- ZooKeeper(3)-内部原理
一. 节点类型 二. Stat结构体 1)czxid-创建节点的事务zxid 每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID. 事务ID是ZooKee ...
- Python学习第二弹
昨天补充: 编码: Unicode ; utf-8 ; GBK 关系: 关键字:1. continue 终止当前循环,进行下一次循环 2. break 终止循环 题6解法2: ...
- C语言程序设计·谭浩强(第四版)第二章课后习题的答案,算法——程序的灵魂
C语言程序小练习 1.用C语言设计程序算出1-1/2+1/3-14+1/5...+1/99-1/100的值 #include<stdio.h> int main() { ; double ...