v1.4 版本发布,修复bug、优化细节、新增定时任务管理,详细信息查看发行版说明

pull/111/head
郑杰 2019-01-08 16:53:23 +08:00
parent 588bff0219
commit 68e62678fc
30 changed files with 1184 additions and 45 deletions

View File

@ -24,6 +24,18 @@
- 密码: 123456
#### 开发环境
- JDK8
- IDEIntelliJ IDEA (后端)
- IDEJetBrains WebStorm (前端)
- 依赖管理Maven
- 数据库MySQL 5.5.59
#### 系统功能模块
- 用户管理 提供用户的相关配置
@ -36,6 +48,7 @@
- redis管理 将redis的操作可视化提供对redis的基本操作
- redis限流 对系统的流量进行控制,由[everhopingandwaiting](https://github.com/everhopingandwaiting)提供
- SQL监控 采用 druid 监控数据库访问性能
- 定时任务管理 整合quartz做定时任务
- 三方工具: 邮件工具sm.ms免费图床支付宝支付七牛云存储
- 富文本编辑器

View File

@ -11,7 +11,7 @@
Target Server Version : 50559
File Encoding : 65001
Date: 06/01/2019 13:09:59
Date: 08/01/2019 16:17:02
*/
SET NAMES utf8mb4;
@ -71,7 +71,7 @@ CREATE TABLE `log` (
`time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4553 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
) ENGINE = InnoDB AUTO_INCREMENT = 5066 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for menu
@ -88,7 +88,7 @@ CREATE TABLE `menu` (
`icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of menu
@ -105,17 +105,19 @@ INSERT INTO `menu` VALUES (9, '2018-12-18 15:19:34', b'1', 'SQL监控', NULL, 6,
INSERT INTO `menu` VALUES (10, '2018-12-19 13:38:16', b'0', '组件管理', NULL, 0, 50, 'zujian', 'components');
INSERT INTO `menu` VALUES (11, '2018-12-19 13:38:49', b'0', '图标库', 'components/IconSelect', 10, 51, 'icon', 'icon');
INSERT INTO `menu` VALUES (12, '2018-12-24 20:37:35', b'0', '实时控制台', 'monitor/log/msg', 6, 13, 'codeConsole', 'msg');
INSERT INTO `menu` VALUES (13, '2018-12-27 10:11:26', b'0', '三方工具', '', 0, 20, 'tools', 'tools');
INSERT INTO `menu` VALUES (14, '2018-12-27 10:13:09', b'0', '邮件工具', 'tools/email/index', 13, 21, 'email', 'email');
INSERT INTO `menu` VALUES (13, '2018-12-27 10:11:26', b'0', '三方工具', '', 0, 30, 'tools', 'tools');
INSERT INTO `menu` VALUES (14, '2018-12-27 10:13:09', b'0', '邮件工具', 'tools/email/index', 13, 31, 'email', 'email');
INSERT INTO `menu` VALUES (15, '2018-12-27 11:58:25', b'0', '富文本', 'components/Editor', 10, 52, 'fwb', 'tinymce');
INSERT INTO `menu` VALUES (16, '2018-12-28 09:36:53', b'0', 'SM.MS图床', 'tools/picture/index', 13, 22, 'image', 'pictures');
INSERT INTO `menu` VALUES (16, '2018-12-28 09:36:53', b'0', 'SM.MS图床', 'tools/picture/index', 13, 32, 'image', 'pictures');
INSERT INTO `menu` VALUES (17, '2018-12-28 15:09:49', b'1', '项目地址', '', 0, 0, 'github', 'https://github.com/elunez/eladmin');
INSERT INTO `menu` VALUES (18, '2018-12-31 11:12:15', b'0', '七牛云存储', 'tools/qiniu/index', 13, 23, 'qiniu', 'qiniu');
INSERT INTO `menu` VALUES (19, '2018-12-31 14:52:38', b'0', '支付宝工具', 'tools/aliPay/index', 13, 24, 'alipay', 'aliPay');
INSERT INTO `menu` VALUES (21, '2019-01-04 16:22:03', b'0', '多级菜单', '', 0, 900, 'menu', 'menu1');
INSERT INTO `menu` VALUES (22, '2019-01-04 16:23:29', b'0', '二级菜单1', '', 21, 999, 'menu', 'menu1-1');
INSERT INTO `menu` VALUES (23, '2019-01-04 16:23:57', b'0', '二级菜单2', '', 21, 999, 'menu', 'menu1-2');
INSERT INTO `menu` VALUES (24, '2019-01-04 16:24:48', b'1', '三级菜单', '', 22, 999, 'chain', 'https://github.com/elunez/eladmin');
INSERT INTO `menu` VALUES (18, '2018-12-31 11:12:15', b'0', '七牛云存储', 'tools/qiniu/index', 13, 33, 'qiniu', 'qiniu');
INSERT INTO `menu` VALUES (19, '2018-12-31 14:52:38', b'0', '支付宝工具', 'tools/aliPay/index', 13, 34, 'alipay', 'aliPay');
INSERT INTO `menu` VALUES (21, '2019-01-04 16:22:03', b'0', '多级菜单', '', 0, 900, 'menu', 'nested');
INSERT INTO `menu` VALUES (22, '2019-01-04 16:23:29', b'0', '二级菜单1', 'nested/menu1/index', 21, 999, 'menu', 'menu1');
INSERT INTO `menu` VALUES (23, '2019-01-04 16:23:57', b'0', '二级菜单2', 'nested/menu2/index', 21, 999, 'menu', 'menu2');
INSERT INTO `menu` VALUES (24, '2019-01-04 16:24:48', b'0', '三级菜单1', 'nested/menu1/menu1-1', 22, 999, 'menu', 'menu1-1');
INSERT INTO `menu` VALUES (27, '2019-01-07 17:27:32', b'0', '三级菜单2', 'nested/menu1/menu1-2', 22, 999, 'menu', 'menu1-2');
INSERT INTO `menu` VALUES (28, '2019-01-07 20:34:40', b'0', '定时任务', 'system/timing/index', 1, 6, 'timing', 'timing');
-- ----------------------------
-- Table structure for menus_roles
@ -156,6 +158,8 @@ INSERT INTO `menus_roles` VALUES (21, 1);
INSERT INTO `menus_roles` VALUES (22, 1);
INSERT INTO `menus_roles` VALUES (23, 1);
INSERT INTO `menus_roles` VALUES (24, 1);
INSERT INTO `menus_roles` VALUES (27, 1);
INSERT INTO `menus_roles` VALUES (28, 1);
INSERT INTO `menus_roles` VALUES (1, 2);
INSERT INTO `menus_roles` VALUES (2, 2);
INSERT INTO `menus_roles` VALUES (3, 2);
@ -174,6 +178,8 @@ INSERT INTO `menus_roles` VALUES (21, 2);
INSERT INTO `menus_roles` VALUES (22, 2);
INSERT INTO `menus_roles` VALUES (23, 2);
INSERT INTO `menus_roles` VALUES (24, 2);
INSERT INTO `menus_roles` VALUES (27, 2);
INSERT INTO `menus_roles` VALUES (28, 2);
-- ----------------------------
-- Table structure for permission
@ -186,7 +192,7 @@ CREATE TABLE `permission` (
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pid` int(11) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of permission
@ -221,6 +227,11 @@ INSERT INTO `permission` VALUES (30, '菜单查询', '2018-12-28 17:34:41', 'MEN
INSERT INTO `permission` VALUES (31, '菜单创建', '2018-12-28 17:34:52', 'MENU_CREATE', 29);
INSERT INTO `permission` VALUES (32, '菜单编辑', '2018-12-28 17:35:20', 'MENU_EDIT', 29);
INSERT INTO `permission` VALUES (33, '菜单删除', '2018-12-28 17:35:29', 'MENU_DELETE', 29);
INSERT INTO `permission` VALUES (35, '定时任务管理', '2019-01-08 14:59:57', 'JOB_ALL', 0);
INSERT INTO `permission` VALUES (36, '任务查询', '2019-01-08 15:00:09', 'JOB_SELECT', 35);
INSERT INTO `permission` VALUES (37, '任务创建', '2019-01-08 15:00:20', 'JOB_CREATE', 35);
INSERT INTO `permission` VALUES (38, '任务编辑', '2019-01-08 15:00:33', 'JOB_EDIT', 35);
INSERT INTO `permission` VALUES (39, '任务删除', '2019-01-08 15:01:13', 'JOB_DELETE', 35);
-- ----------------------------
-- Table structure for picture
@ -269,6 +280,48 @@ CREATE TABLE `qiniu_content` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for quartz_job
-- ----------------------------
DROP TABLE IF EXISTS `quartz_job`;
CREATE TABLE `quartz_job` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bean_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`is_pause` bit(1) NULL DEFAULT NULL,
`jobName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`updateTime` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of quartz_job
-- ----------------------------
INSERT INTO `quartz_job` VALUES (1, 'visitsTask', '0 0 0 * * ?', b'0', '更新访客记录', 'run', NULL, '每日0点创建新的访客记录', '2019-01-08 14:53:31');
INSERT INTO `quartz_job` VALUES (2, 'testTask', '0/5 * * * * ?', b'1', '测试1', 'run1', 'test', '带参测试多参使用json', '2019-01-08 14:53:25');
INSERT INTO `quartz_job` VALUES (3, 'testTask', '0/5 * * * * ?', b'1', '测试', 'run', '', '不带参测试', '2019-01-08 15:56:54');
-- ----------------------------
-- Table structure for quartz_log
-- ----------------------------
DROP TABLE IF EXISTS `quartz_log`;
CREATE TABLE `quartz_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`baen_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`createTime` datetime NULL DEFAULT NULL,
`cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`exceptionDetail` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`is_success` bit(1) NULL DEFAULT NULL,
`job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`time` bigint(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 90 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for role
-- ----------------------------
@ -310,6 +363,7 @@ INSERT INTO `roles_permissions` VALUES (2, 14);
INSERT INTO `roles_permissions` VALUES (2, 19);
INSERT INTO `roles_permissions` VALUES (2, 23);
INSERT INTO `roles_permissions` VALUES (2, 30);
INSERT INTO `roles_permissions` VALUES (2, 36);
-- ----------------------------
-- Table structure for user
@ -332,7 +386,7 @@ CREATE TABLE `user` (
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'https://i.loli.net/2018/12/31/5c297270b20e2.jpg', '2018-08-23 09:11:56', 'admin@qq.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'admin', '2018-11-23 10:12:36');
INSERT INTO `user` VALUES (1, 'https://i.loli.net/2018/12/31/5c297270b20e2.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'admin', '2018-11-23 10:12:36');
INSERT INTO `user` VALUES (3, 'https://i.loli.net/2018/12/30/5c2871d6aa101.jpg', '2018-12-27 20:05:26', 'test@qq.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'test', NULL);
-- ----------------------------
@ -367,7 +421,7 @@ CREATE TABLE `verification_code` (
`value` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scenes` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 33 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for visits
@ -381,6 +435,6 @@ CREATE TABLE `visits` (
`weekDay` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`createTime` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 51 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
) ENGINE = InnoDB AUTO_INCREMENT = 54 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -1,8 +1,9 @@
package me.zhengjie;
import me.zhengjie.common.utils.SpringContextHolder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
@ -11,7 +12,6 @@ import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBr
* @date 2018/11/15 9:20:19
*/
@SpringBootApplication
@EnableScheduling
@EnableTransactionManagement
@EnableWebSocketMessageBroker
public class AppRun {
@ -19,4 +19,9 @@ public class AppRun {
public static void main(String[] args) {
SpringApplication.run(AppRun.class, args);
}
@Bean
public SpringContextHolder springContextHolder() {
return new SpringContextHolder();
}
}

View File

@ -0,0 +1,22 @@
package me.zhengjie.common.config;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.*;
/**
* @author jie
* @date 2019-01-08
*/
@Configuration
public class ThreadPoolConfig {
@Bean
public ExecutorService getThreadPool(){
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-call-runner-%d").build();
int size = 2;
ExecutorService executorService = new ThreadPoolExecutor(size,size,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),namedThreadFactory);
return executorService;
}
}

View File

@ -76,7 +76,7 @@ public class RedisConfig extends CachingConfigurerSupport {
public RedisCacheConfiguration redisCacheConfiguration(){
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofDays(30));
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(2));
return configuration;
}
@ -95,6 +95,7 @@ public class RedisConfig extends CachingConfigurerSupport {
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.system.service.dto");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.system.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.tools.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.quartz.domain");
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());

View File

@ -26,7 +26,12 @@ import java.util.List;
@Configuration
@EnableSwagger2
@ComponentScan(basePackages = {"me.zhengjie.core.rest","me.zhengjie.system.rest","me.zhengjie.system.monitor"})
@ComponentScan(basePackages = {
"me.zhengjie.core.rest",
"me.zhengjie.system.rest",
"me.zhengjie.monitor.rest",
"me.zhengjie.quartz.rest",
"me.zhengjie.tools.rest",})
public class SwaggerConfig {
@Bean

View File

@ -0,0 +1,73 @@
package me.zhengjie.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author
* @date 2019-01-07
*/
@Slf4j
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
/**
* ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
assertContextInjected();
return applicationContext;
}
/**
* applicationContextBean, .
*/
public static <T> T getBean(String name) {
assertContextInjected();
return (T) applicationContext.getBean(name);
}
/**
* applicationContextBean, .
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}
/**
* ApplicationContext.
*/
private static void assertContextInjected() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
}
}
/**
* SpringContextHolderApplicationContextNull.
*/
public static void clearHolder() {
log.debug("清除SpringContextHolder中的ApplicationContext:"
+ applicationContext);
applicationContext = null;
}
@Override
public void destroy() throws Exception {
SpringContextHolder.clearHolder();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringContextHolder.applicationContext != null) {
log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
}
SpringContextHolder.applicationContext = applicationContext;
}
}

View File

@ -27,7 +27,6 @@ public class LoggerQueue {
/**
*
*
* @param log
* @return
*/

View File

@ -1,18 +1,17 @@
package me.zhengjie.monitor.config;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.monitor.service.VisitsService;
import org.springframework.context.annotation.Configuration;
/**
*
* @author jie
*/
@Slf4j
@Configuration
public class VisitsInitialization {
public VisitsInitialization(VisitsService visitsService){
log.info("--------------- 初始化站点统计,如果存在今日统计则跳过 ---------------");
System.out.println("--------------- 初始化站点统计,如果存在今日统计则跳过 ---------------");
visitsService.save();
}
}

View File

@ -1,6 +1,7 @@
package me.zhengjie.monitor.config;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.monitor.domain.LogMessage;
import org.springframework.beans.factory.annotation.Autowired;
@ -9,8 +10,7 @@ import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.*;
/**
* WebSocketstomp
@ -24,6 +24,9 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Autowired
private ExecutorService executorService;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket")
@ -36,9 +39,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
*/
@PostConstruct
public void pushLogger(){
ExecutorService executorService= Executors.newFixedThreadPool(2);
Runnable runnable=new Runnable() {
@Override
public void run() {
while (true) {
@ -63,6 +64,5 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
}
};
executorService.submit(runnable);
executorService.submit(runnable);
}
}

View File

@ -46,10 +46,10 @@ public class RedisController {
}
@Log(description = "删除Redis缓存")
@DeleteMapping(value = "/redis/{key}")
@DeleteMapping(value = "/redis")
@PreAuthorize("hasAnyRole('ADMIN','REDIS_ALL','REDIS_DELETE')")
public ResponseEntity delete(@PathVariable String key){
redisService.delete(key);
public ResponseEntity delete(@RequestBody RedisVo resources){
redisService.delete(resources.getKey());
return new ResponseEntity(HttpStatus.OK);
}

View File

@ -0,0 +1,39 @@
package me.zhengjie.quartz.config;
import me.zhengjie.quartz.domain.QuartzJob;
import me.zhengjie.quartz.repository.QuartzJobRepository;
import me.zhengjie.quartz.utils.QuartzManage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author jie
* @date 2019-01-07
*/
@Component
public class JobRunner implements ApplicationRunner {
@Autowired
private QuartzJobRepository quartzJobRepository;
@Autowired
private QuartzManage quartzManage;
/**
*
* @param applicationArguments
* @throws Exception
*/
@Override
public void run(ApplicationArguments applicationArguments){
System.out.println("--------------------注入定时任务---------------------");
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
quartzJobs.forEach(quartzJob -> {
quartzManage.addJob(quartzJob);
});
System.out.println("--------------------定时任务注入完成---------------------");
}
}

View File

@ -0,0 +1,55 @@
package me.zhengjie.quartz.config;
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.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
/**
*
* @author
* @date 2019-01-07
*/
@Configuration
public class QuartzConfig {
/**
* JobSpring Beannull
*/
@Component("quartzJobFactory")
public class QuartzJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
/**
* schedulerspring
* @param quartzJobFactory
* @return
* @throws Exception
*/
@Bean(name = "scheduler")
public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception {
SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
factoryBean.setJobFactory(quartzJobFactory);
factoryBean.afterPropertiesSet();
Scheduler scheduler=factoryBean.getScheduler();
scheduler.start();
return scheduler;
}
}

View File

@ -0,0 +1,75 @@
package me.zhengjie.quartz.domain;
import lombok.Data;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author jie
* @date 2019-01-07
*/
@Data
@Entity
@Table(name = "quartz_job")
public class QuartzJob implements Serializable {
public static final String JOB_KEY = "JOB_KEY";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
*
*/
private String jobName;
/**
* Bean
*/
@Column(name = "bean_name")
@NotBlank
private String beanName;
/**
*
*/
@Column(name = "method_name")
@NotBlank
private String methodName;
/**
*
*/
@Column(name = "params")
private String params;
/**
* cron
*/
@Column(name = "cron_expression")
@NotBlank
private String cronExpression;
/**
*
*/
@Column(name = "is_pause")
private Boolean isPause = false;
/**
*
*/
@Column(name = "remark")
@NotBlank
private String remark;
/**
*
*/
@UpdateTimestamp
private Timestamp updateTime;
}

View File

@ -0,0 +1,74 @@
package me.zhengjie.quartz.domain;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author jie
* @date 2019-01-07
*/
@Entity
@Data
@Table(name = "quartz_log")
public class QuartzLog implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
*
*/
@Column(name = "job_name")
private String jobName;
/**
* Bean
*/
@Column(name = "baen_name")
private String beanName;
/**
*
*/
@Column(name = "method_name")
private String methodName;
/**
*
*/
@Column(name = "params")
private String params;
/**
* cron
*/
@Column(name = "cron_expression")
private String cronExpression;
/**
*
*/
@Column(name = "is_success")
private Boolean isSuccess;
/**
*
*/
@Column(columnDefinition = "text")
private String exceptionDetail;
/**
*
*/
private Long time;
/**
*
*/
@CreationTimestamp
private Timestamp createTime;
}

View File

@ -0,0 +1,31 @@
package me.zhengjie.quartz.repository;
import me.zhengjie.quartz.domain.QuartzJob;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author jie
* @date 2019-01-07
*/
public interface QuartzJobRepository extends JpaRepository<QuartzJob,Long>, JpaSpecificationExecutor {
/**
*
* @param id
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@Query(value = "update quartz_job set is_pause = 1 where id = ?1",nativeQuery = true)
void updateIsPause(Long id);
/**
*
* @return
*/
List<QuartzJob> findByIsPauseIsFalse();
}

View File

@ -0,0 +1,13 @@
package me.zhengjie.quartz.repository;
import me.zhengjie.quartz.domain.QuartzLog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author jie
* @date 2019-01-07
*/
public interface QuartzLogRepository extends JpaRepository<QuartzLog,Long>, JpaSpecificationExecutor {
}

View File

@ -0,0 +1,102 @@
package me.zhengjie.quartz.rest;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.aop.log.Log;
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.quartz.domain.QuartzJob;
import me.zhengjie.quartz.domain.QuartzLog;
import me.zhengjie.quartz.service.QuartzJobService;
import me.zhengjie.quartz.service.query.QuartzJobQueryService;
import me.zhengjie.quartz.service.query.QuartzLogQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author jie
* @date 2019-01-07
*/
@Slf4j
@RestController
@RequestMapping("/api")
public class QuartzJobController {
private static final String ENTITY_NAME = "quartzJob";
@Autowired
private QuartzJobService quartzJobService;
@Autowired
private QuartzJobQueryService quartzJobQueryService;
@Autowired
private QuartzLogQueryService quartzLogQueryService;
@Log(description = "查询定时任务")
@GetMapping(value = "/jobs")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_SELECT')")
public ResponseEntity getJobs(QuartzJob resources, Pageable pageable){
return new ResponseEntity(quartzJobQueryService.queryAll(resources,pageable), HttpStatus.OK);
}
/**
*
* @param resources
* @param pageable
* @return
*/
@GetMapping(value = "/jobLogs")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_SELECT')")
public ResponseEntity getJobLogs(QuartzLog resources, Pageable pageable){
return new ResponseEntity(quartzLogQueryService.queryAll(resources,pageable), HttpStatus.OK);
}
@Log(description = "新增定时任务")
@PostMapping(value = "/jobs")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_CREATE')")
public ResponseEntity create(@Validated @RequestBody QuartzJob resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
return new ResponseEntity(quartzJobService.create(resources),HttpStatus.CREATED);
}
@Log(description = "修改定时任务")
@PutMapping(value = "/jobs")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')")
public ResponseEntity update(@Validated @RequestBody QuartzJob resources){
if (resources.getId() == null) {
throw new BadRequestException(ENTITY_NAME +" ID Can not be empty");
}
quartzJobService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log(description = "更改定时任务状态")
@PutMapping(value = "/jobs/{id}")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')")
public ResponseEntity updateIsPause(@PathVariable Long id){
quartzJobService.updateIsPause(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log(description = "执行定时任务")
@PutMapping(value = "/jobs/exec/{id}")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')")
public ResponseEntity execution(@PathVariable Long id){
quartzJobService.execution(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log(description = "删除定时任务")
@DeleteMapping(value = "/jobs/{id}")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
quartzJobService.delete(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.OK);
}
}

View File

@ -0,0 +1,58 @@
package me.zhengjie.quartz.service;
import me.zhengjie.quartz.domain.QuartzJob;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
/**
* @author
* @date 2018/10/05 19:17:38
*/
@CacheConfig(cacheNames = "quartzJob")
public interface QuartzJobService {
/**
* create
* @param resources
* @return
*/
@CacheEvict(allEntries = true)
QuartzJob create(QuartzJob resources);
/**
* update
* @param resources
* @return
*/
@CacheEvict(allEntries = true)
void update(QuartzJob resources);
/**
* del
* @param quartzJob
*/
@CacheEvict(allEntries = true)
void delete(QuartzJob quartzJob);
/**
* findById
* @param id
* @return
*/
@Cacheable(key = "#p0")
QuartzJob findById(Long id);
/**
*
* @param quartzJob
*/
@CacheEvict(allEntries = true)
void updateIsPause(QuartzJob quartzJob);
/**
*
* @param quartzJob
*/
void execution(QuartzJob quartzJob);
}

View File

@ -0,0 +1,94 @@
package me.zhengjie.quartz.service.impl;
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.common.utils.ValidationUtil;
import me.zhengjie.quartz.domain.QuartzJob;
import me.zhengjie.quartz.repository.QuartzJobRepository;
import me.zhengjie.quartz.service.QuartzJobService;
import me.zhengjie.quartz.utils.QuartzManage;
import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
/**
* @author jie
* @date 2019-01-07
*/
@Service(value = "quartzJobService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class QuartzJobServiceImpl implements QuartzJobService {
@Autowired
private QuartzJobRepository quartzJobRepository;
@Autowired
private QuartzManage quartzManage;
@Override
public QuartzJob findById(Long id) {
Optional<QuartzJob> quartzJob = quartzJobRepository.findById(id);
ValidationUtil.isNull(quartzJob,"QuartzJob","id",id);
return quartzJob.get();
}
@Override
@Transactional(rollbackFor = Exception.class)
public QuartzJob create(QuartzJob resources) {
if (!CronExpression.isValidExpression(resources.getCronExpression())){
throw new BadRequestException("cron表达式格式错误");
}
resources = quartzJobRepository.save(resources);
quartzManage.addJob(resources);
return resources;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(QuartzJob resources) {
if(resources.getId().equals(1L)){
throw new BadRequestException("该任务不可操作");
}
if (!CronExpression.isValidExpression(resources.getCronExpression())){
throw new BadRequestException("cron表达式格式错误");
}
resources = quartzJobRepository.save(resources);
quartzManage.updateJobCron(resources);
}
@Override
public void updateIsPause(QuartzJob quartzJob) {
if(quartzJob.getId().equals(1L)){
throw new BadRequestException("该任务不可操作");
}
if (quartzJob.getIsPause()) {
quartzManage.resumeJob(quartzJob);
quartzJob.setIsPause(false);
} else {
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(true);
}
quartzJobRepository.save(quartzJob);
}
@Override
public void execution(QuartzJob quartzJob) {
if(quartzJob.getId().equals(1L)){
throw new BadRequestException("该任务不可操作");
}
quartzManage.runAJobNow(quartzJob);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(QuartzJob quartzJob) {
if(quartzJob.getId().equals(1L)){
throw new BadRequestException("该任务不可操作");
}
quartzManage.deleteJob(quartzJob);
quartzJobRepository.delete(quartzJob);
}
}

View File

@ -0,0 +1,64 @@
package me.zhengjie.quartz.service.query;
import me.zhengjie.common.utils.PageUtil;
import me.zhengjie.quartz.domain.QuartzJob;
import me.zhengjie.quartz.repository.QuartzJobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
/**
* @author jie
* @date 2019-01-07
*/
@Service
@CacheConfig(cacheNames = "quartzJob")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class QuartzJobQueryService {
@Autowired
private QuartzJobRepository quartzJobRepository;
@Cacheable(keyGenerator = "keyGenerator")
public Object queryAll(QuartzJob quartzJob, Pageable pageable){
return PageUtil.toPage(quartzJobRepository.findAll(new Spec(quartzJob),pageable));
}
class Spec implements Specification<QuartzJob> {
private QuartzJob quartzJob;
public Spec(QuartzJob quartzJob){
this.quartzJob = quartzJob;
}
@Override
public Predicate toPredicate(Root<QuartzJob> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
if(!ObjectUtils.isEmpty(quartzJob.getJobName())){
/**
*
*/
list.add(cb.like(root.get("jobName").as(String.class),"%"+quartzJob.getJobName()+"%"));
}
Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p));
}
}
}

View File

@ -0,0 +1,64 @@
package me.zhengjie.quartz.service.query;
import me.zhengjie.common.utils.PageUtil;
import me.zhengjie.quartz.domain.QuartzLog;
import me.zhengjie.quartz.repository.QuartzLogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
/**
* @author jie
* @date 2019-01-07
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class QuartzLogQueryService {
@Autowired
private QuartzLogRepository quartzLogRepository;
public Object queryAll(QuartzLog quartzLog, Pageable pageable){
return PageUtil.toPage(quartzLogRepository.findAll(new Spec(quartzLog),pageable));
}
class Spec implements Specification<QuartzLog> {
private QuartzLog quartzLog;
public Spec(QuartzLog quartzLog){
this.quartzLog = quartzLog;
}
@Override
public Predicate toPredicate(Root<QuartzLog> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
if(!ObjectUtils.isEmpty(quartzLog.getJobName())){
/**
*
*/
list.add(cb.like(root.get("jobName").as(String.class),"%"+quartzLog.getJobName()+"%"));
}
if (!ObjectUtils.isEmpty(quartzLog.getIsSuccess())) {
list.add(cb.equal(root.get("isSuccess").as(Boolean.class), quartzLog.getIsSuccess()));
}
Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p));
}
}
}

View File

@ -0,0 +1,22 @@
package me.zhengjie.quartz.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
*
* @author jie
* @date 2019-01-08
*/
@Slf4j
@Component
public class TestTask {
public void run(){
log.info("执行成功");
}
public void run1(String str){
log.info("执行成功,参数为: {}" + str);
}
}

View File

@ -1,9 +1,7 @@
package me.zhengjie.monitor.config;
package me.zhengjie.quartz.task;
import me.zhengjie.monitor.service.VisitsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
@ -11,17 +9,12 @@ import org.springframework.stereotype.Component;
* @date 2018-12-25
*/
@Component
@Async
public class VisitsScheduling {
public class VisitsTask {
@Autowired
private VisitsService visitsService;
/**
* 0
*/
@Scheduled(cron = "0 0 0 * * ?")
public void save(){
public void run(){
visitsService.save();
}
}

View File

@ -0,0 +1,78 @@
package me.zhengjie.quartz.utils;
import me.zhengjie.common.utils.SpringContextHolder;
import me.zhengjie.common.utils.ThrowableUtil;
import me.zhengjie.quartz.domain.QuartzJob;
import me.zhengjie.quartz.domain.QuartzLog;
import me.zhengjie.quartz.repository.QuartzLogRepository;
import me.zhengjie.quartz.service.QuartzJobService;
import org.quartz.JobExecutionContext;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;
import javax.annotation.Resource;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* https://gitee.com/renrenio/renren-security
* @author
* @date 2019-01-07
*/
@Async
public class ExecutionJob extends QuartzJobBean {
@Resource(name = "scheduler")
private Scheduler scheduler;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ExecutorService executorService;
@Override
protected void executeInternal(JobExecutionContext context) {
QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
// 获取spring bean
QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean("quartzLogRepository");
QuartzJobService quartzJobService = SpringContextHolder.getBean("quartzJobService");
QuartzManage quartzManage = SpringContextHolder.getBean("quartzManage");
QuartzLog log = new QuartzLog();
log.setJobName(quartzJob.getJobName());
log.setBeanName(quartzJob.getBeanName());
log.setMethodName(quartzJob.getMethodName());
log.setParams(quartzJob.getParams());
long startTime = System.currentTimeMillis();
log.setCronExpression(quartzJob.getCronExpression());
try {
// 执行任务
logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName());
QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
quartzJob.getParams());
Future<?> future = executorService.submit(task);
future.get();
long times = System.currentTimeMillis() - startTime;
log.setTime(times);
// 任务状态
log.setIsSuccess(true);
logger.info("任务执行完毕,任务名称:{} 总共耗时:{} 毫秒", quartzJob.getJobName(), times);
} catch (Exception e) {
logger.error("任务执行失败,任务名称:{}" + quartzJob.getJobName(), e);
long times = System.currentTimeMillis() - startTime;
log.setTime(times);
// 任务状态 0成功 1失败
log.setIsSuccess(false);
log.setExceptionDetail(ThrowableUtil.getStackTrace(e));
//出错就暂停任务
quartzManage.pauseJob(quartzJob);
//更新状态
quartzJobService.updateIsPause(quartzJob);
} finally {
quartzLogRepository.save(log);
}
}
}

View File

@ -0,0 +1,156 @@
package me.zhengjie.quartz.utils;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.quartz.domain.QuartzJob;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* @author jie
* @date 2019-01-07
*/
@Slf4j
@Component
public class QuartzManage {
private static final String JOB_NAME = "TASK_";
@Resource(name = "scheduler")
private Scheduler scheduler;
public void addJob(QuartzJob quartzJob){
try {
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class).
withIdentity(JOB_NAME + quartzJob.getId()).build();
//通过触发器名和cron 表达式创建 Trigger
Trigger cronTrigger = newTrigger()
.withIdentity(JOB_NAME + quartzJob.getId())
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
.build();
cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);
//重置启动时间
((CronTriggerImpl)cronTrigger).setStartTime(new Date());
//执行定时任务
scheduler.scheduleJob(jobDetail,cronTrigger);
// 暂停任务
if (quartzJob.getIsPause()) {
pauseJob(quartzJob);
}
} catch (Exception e){
log.error("创建定时任务失败", e);
throw new BadRequestException(e.getMessage());
}
}
/**
* job cron
* @param quartzJob
* @throws SchedulerException
*/
public void updateJobCron(QuartzJob quartzJob){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//重置启动时间
((CronTriggerImpl)trigger).setStartTime(new Date());
scheduler.rescheduleJob(triggerKey, trigger);
// 暂停任务
if (quartzJob.getIsPause()) {
pauseJob(quartzJob);
}
} catch (Exception e){
log.error("更新定时任务失败", e);
throw new BadRequestException(e.getMessage());
}
}
/**
* job
* @param quartzJob
* @throws SchedulerException
*/
public void deleteJob(QuartzJob quartzJob){
try {
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
scheduler.deleteJob(jobKey);
} catch (Exception e){
log.error("删除定时任务失败", e);
throw new BadRequestException(e.getMessage());
}
}
/**
* job
* @param quartzJob
* @throws SchedulerException
*/
public void resumeJob(QuartzJob quartzJob){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 如果不存在则创建一个定时任务
if(trigger == null){
addJob(quartzJob);
}
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
scheduler.resumeJob(jobKey);
} catch (Exception e){
log.error("恢复定时任务失败", e);
throw new BadRequestException(e.getMessage());
}
}
/**
* job
* @param quartzJob
* @throws SchedulerException
*/
public void runAJobNow(QuartzJob quartzJob){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 如果不存在则创建一个定时任务
if(trigger == null){
addJob(quartzJob);
}
JobDataMap dataMap = new JobDataMap();
dataMap.put(QuartzJob.JOB_KEY, quartzJob);
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
scheduler.triggerJob(jobKey,dataMap);
} catch (Exception e){
log.error("定时任务执行失败", e);
throw new BadRequestException(e.getMessage());
}
}
/**
* job
* @param quartzJob
* @throws SchedulerException
*/
public void pauseJob(QuartzJob quartzJob){
try {
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
scheduler.pauseJob(jobKey);
} catch (Exception e){
log.error("定时任务暂停失败", e);
throw new BadRequestException(e.getMessage());
}
}
}

View File

@ -0,0 +1,48 @@
package me.zhengjie.quartz.utils;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.utils.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
/**
*
* @author
*/
@Slf4j
public class QuartzRunnable implements Runnable {
private Object target;
private Method method;
private String params;
QuartzRunnable(String beanName, String methodName, String params)
throws NoSuchMethodException, SecurityException {
this.target = SpringContextHolder.getBean(beanName);
this.params = params;
if (StringUtils.isNotBlank(params)) {
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
} else {
this.method = target.getClass().getDeclaredMethod(methodName);
}
}
@Override
public void run() {
try {
ReflectionUtils.makeAccessible(method);
if (StringUtils.isNotBlank(params)) {
method.invoke(target, params);
} else {
method.invoke(target);
}
} catch (Exception e) {
log.error("定时任务执行失败",e);
}
}
}

View File

@ -162,13 +162,15 @@ public class MenuServiceImpl implements MenuService {
if(menuDTO.getPid().equals(0L)){
//一级目录需要加斜杠,不然访问不了
menuVo.setPath("/" + menuDTO.getPath());
menuVo.setRedirect("noredirect");
menuVo.setComponent(StrUtil.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent());
}else if(!StrUtil.isEmpty(menuDTO.getComponent())){
menuVo.setComponent(menuDTO.getComponent());
}
menuVo.setComponent(StrUtil.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent());
}
menuVo.setMeta(new MenuMetaVo(menuDTO.getName(),menuDTO.getIcon()));
if(menuDTOList!=null && menuDTOList.size()!=0){
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenus(menuDTOList));
// 处理是一级菜单并且没有子菜单的情况
} else if(menuDTO.getPid().equals(0L)){

View File

@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

View File

@ -46,7 +46,6 @@ spring:
jpa:
properties:
hibernate:
show_sql: true
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: update