feat(新增): 添加任务调度
This commit is contained in:
parent
04273ecf39
commit
05496e16a8
|
@ -26,6 +26,8 @@
|
|||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="auto">
|
||||
#foreach($item in $baseFieldList)
|
||||
|
||||
// $item.annotation
|
||||
<el-form-item :label="$t('${lowercaseName}_${item.name}')" prop="$item.name">
|
||||
<el-input v-model="form.$item.name" autocomplete="off" type="text" :placeholder="$t('input') + $t('${lowercaseName}_${item.name}')" />
|
||||
</el-form-item>
|
||||
|
|
|
@ -40,11 +40,6 @@ public class SchedulersAddDto {
|
|||
@NotNull(message = "corn表达式不能为空")
|
||||
private String cronExpression;
|
||||
|
||||
@Schema(name = "jobMethodName", title = "执行方法")
|
||||
@NotBlank(message = "执行方法不能为空")
|
||||
@NotNull(message = "执行方法不能为空")
|
||||
private String jobMethodName;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ public enum ResultCodeEnum {
|
|||
ILLEGAL_CALLBACK_REQUEST_ERROR(217, "非法回调请求"),
|
||||
FETCH_USERINFO_ERROR(219, "获取用户信息失败"),
|
||||
ILLEGAL_DATA_REQUEST(219, "非法数据请求"),
|
||||
CLASS_NOT_FOUND(219, "类名不存在"),
|
||||
|
||||
// 无权访问 403
|
||||
FAIL_REQUEST_NOT_AUTH(403, "用户未认证"),
|
||||
|
|
|
@ -33,4 +33,7 @@ public class SchedulersVo {
|
|||
@Schema(name = "triggerState", title = "triggerState触发器状态")
|
||||
private String triggerState;
|
||||
|
||||
@Schema(name = "cronExpression", title = "corn表达式")
|
||||
private String cronExpression;
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package cn.bunny.services.aop;
|
||||
|
||||
import cn.bunny.common.service.exception.BunnyException;
|
||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* * 扫描指定目录下所有类
|
||||
*/
|
||||
@Component
|
||||
public class AnnotationScanner {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<Class<?>> getClassesWithAnnotation(Class<?> annotation) {
|
||||
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter((Class<? extends Annotation>) annotation));
|
||||
|
||||
Set<Class<?>> classes = new HashSet<>();
|
||||
for (BeanDefinition bd : scanner.findCandidateComponents("cn.bunny.services")) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(bd.getBeanClassName());
|
||||
classes.add(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new BunnyException(ResultCodeEnum.CLASS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package cn.bunny.services.aop.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface QuartzSchedulers {
|
||||
String value() default "";
|
||||
|
||||
String description();
|
||||
}
|
|
@ -18,6 +18,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Schedulers视图表 前端控制器
|
||||
|
@ -47,6 +50,13 @@ public class SchedulersController {
|
|||
return Mono.just(Result.success(pageResult));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有可用调度任务", description = "获取所有可用调度任务")
|
||||
@GetMapping("getAllScheduleJobList")
|
||||
public Mono<Result<List<Map<String, String>>>> getAllScheduleJobList() {
|
||||
List<Map<String, String>> mapList = schedulersService.getAllScheduleJobList();
|
||||
return Mono.just(Result.success(mapList));
|
||||
}
|
||||
|
||||
@Operation(summary = "添加Schedulers任务", description = "添加Schedulers任务")
|
||||
@PostMapping("addSchedulers")
|
||||
public Mono<Result<String>> addSchedulers(@Valid @RequestBody SchedulersAddDto dto) {
|
||||
|
|
|
@ -49,6 +49,13 @@ public class SchedulersGroupController {
|
|||
return Mono.just(Result.success(pageResult));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有任务调度分组", description = "获取所有任务调度分组")
|
||||
@GetMapping("getAllSchedulersGroup")
|
||||
public Mono<Result<List<SchedulersGroupVo>>> getAllSchedulersGroup() {
|
||||
List<SchedulersGroupVo> voList = schedulersGroupService.getAllSchedulersGroup();
|
||||
return Mono.just(Result.success(voList));
|
||||
}
|
||||
|
||||
@Operation(summary = "添加任务调度分组", description = "添加任务调度分组")
|
||||
@PostMapping("addSchedulersGroup")
|
||||
public Mono<Result<String>> addSchedulersGroup(@Valid @RequestBody SchedulersGroupAddDto dto) {
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package cn.bunny.services.quartz;
|
||||
|
||||
import org.quartz.Scheduler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
|
||||
@Configuration
|
||||
public class QuartzConfiguration {
|
||||
|
||||
@Autowired
|
||||
private QuartzJobFactory quartzJobFactory;
|
||||
|
||||
/**
|
||||
* 创建调度器工厂
|
||||
* 1.创建SchedulerFactoryBean
|
||||
* 2.加载自定义的quartz.properties配置文件
|
||||
* 3.设置MyJobFactory
|
||||
*
|
||||
* @return SchedulerFactoryBean
|
||||
*/
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean() {
|
||||
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
|
||||
factoryBean.setAutoStartup(true);
|
||||
// 延时1秒启动
|
||||
factoryBean.setStartupDelay(1);
|
||||
factoryBean.setJobFactory(quartzJobFactory);
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
@Bean(name = "scheduler")
|
||||
public Scheduler scheduler() {
|
||||
return schedulerFactoryBean().getScheduler();
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package cn.bunny.services.quartz;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.scheduling.quartz.AdaptableJobFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class QuartzJobFactory extends AdaptableJobFactory {
|
||||
|
||||
// 这个对象Spring会帮我们自动注入进来
|
||||
@Autowired
|
||||
private AutowireCapableBeanFactory capableBeanFactory;
|
||||
|
||||
// 重写创建Job任务的实例方法
|
||||
@NotNull
|
||||
@Override
|
||||
protected Object createJobInstance(@NotNull TriggerFiredBundle bundle) throws Exception {
|
||||
Object jobInstance = super.createJobInstance(bundle);
|
||||
// 通过以下方式,解决Job任务无法使用Spring中的Bean问题
|
||||
capableBeanFactory.autowireBean(jobInstance);
|
||||
return super.createJobInstance(bundle);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package cn.bunny.services.quartz.job;
|
||||
|
||||
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
@Slf4j
|
||||
@QuartzSchedulers(description = "JobHello任务内容")
|
||||
public class JobHello implements Job {
|
||||
public void start() {
|
||||
log.error("执行任务--JobHello。。。。。。。。。");
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package cn.bunny.services.quartz.job;
|
||||
|
||||
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
@Slf4j
|
||||
@QuartzSchedulers(description = "Demo的类JobHello2")
|
||||
public class JobHello2 implements Job {
|
||||
public void start() {
|
||||
log.error("执行任务---JobHello2。。。。。。。。。");
|
||||
|
|
|
@ -49,4 +49,11 @@ public interface SchedulersGroupService extends IService<SchedulersGroup> {
|
|||
* @param ids 删除id列表
|
||||
*/
|
||||
void deleteSchedulersGroup(List<Long> ids);
|
||||
|
||||
/**
|
||||
* * 获取所有任务调度分组
|
||||
*
|
||||
* @return 获取所有任务分组
|
||||
*/
|
||||
List<SchedulersGroupVo> getAllSchedulersGroup();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Schedulers视图 服务类
|
||||
|
@ -54,4 +57,11 @@ public interface SchedulersService extends IService<Schedulers> {
|
|||
* @param dto Schedulers公共操作表单
|
||||
*/
|
||||
void deleteSchedulers(SchedulersOperationDto dto);
|
||||
|
||||
/**
|
||||
* * 获取所有可用调度任务
|
||||
*
|
||||
* @return 所有调度任务内容
|
||||
*/
|
||||
List<Map<String, String>> getAllScheduleJobList();
|
||||
}
|
||||
|
|
|
@ -89,4 +89,18 @@ public class SchedulersGroupServiceImpl extends ServiceImpl<SchedulersGroupMappe
|
|||
public void deleteSchedulersGroup(List<Long> ids) {
|
||||
baseMapper.deleteBatchIdsWithPhysics(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 获取所有任务调度分组
|
||||
*
|
||||
* @return 获取所有任务分组
|
||||
*/
|
||||
@Override
|
||||
public List<SchedulersGroupVo> getAllSchedulersGroup() {
|
||||
return list().stream().map(schedulersGroup -> {
|
||||
SchedulersGroupVo schedulersGroupVo = new SchedulersGroupVo();
|
||||
BeanUtils.copyProperties(schedulersGroup, schedulersGroupVo);
|
||||
return schedulersGroupVo;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import cn.bunny.dao.dto.schedulers.SchedulersOperationDto;
|
|||
import cn.bunny.dao.entity.schedulers.Schedulers;
|
||||
import cn.bunny.dao.pojo.result.PageResult;
|
||||
import cn.bunny.dao.vo.schedulers.SchedulersVo;
|
||||
import cn.bunny.services.aop.AnnotationScanner;
|
||||
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
||||
import cn.bunny.services.mapper.SchedulersMapper;
|
||||
import cn.bunny.services.service.SchedulersService;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
@ -18,7 +20,10 @@ import org.springframework.beans.BeanUtils;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -34,6 +39,9 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
|||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
private AnnotationScanner annotationScanner;
|
||||
|
||||
/**
|
||||
* * Schedulers视图 服务实现类
|
||||
*
|
||||
|
@ -80,12 +88,13 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
|||
.withIdentity(dto.getJobName(), dto.getJobGroup())
|
||||
.withDescription(dto.getDescription())
|
||||
.build();
|
||||
jobDetail.getJobDataMap().put("jobMethodName", dto.getJobMethodName());
|
||||
jobDetail.getJobDataMap().put("jobMethodName", "execute");
|
||||
|
||||
// 执行任务
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(dto.getCronExpression());
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity("trigger" + dto.getJobName(), dto.getJobGroup())
|
||||
.withIdentity(dto.getJobName(), dto.getJobGroup())
|
||||
.withDescription(dto.getDescription())
|
||||
.startNow()
|
||||
.withSchedule(cronScheduleBuilder).build();
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
|
@ -143,4 +152,26 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
|||
throw new BunnyException(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 获取所有可用调度任务
|
||||
*
|
||||
* @return 所有调度任务内容
|
||||
*/
|
||||
@Override
|
||||
public List<Map<String, String>> getAllScheduleJobList() {
|
||||
Set<Class<?>> classesWithAnnotation = annotationScanner.getClassesWithAnnotation(QuartzSchedulers.class);
|
||||
return classesWithAnnotation.stream().map(cls -> {
|
||||
Map<String, String> hashMap = new HashMap<>();
|
||||
|
||||
// 调度器引用路径
|
||||
String classReference = cls.getName();
|
||||
// 调度器详情
|
||||
String description = cls.getAnnotation(QuartzSchedulers.class).description();
|
||||
|
||||
hashMap.put("value", classReference);
|
||||
hashMap.put("label", description);
|
||||
return hashMap;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ spring:
|
|||
# 如果使用集群,instanceId必须唯一,设置成AUTO
|
||||
instanceId: AUTO
|
||||
jobStore:
|
||||
# 存储方式使用JobStoreTX 也就是数据库
|
||||
# 存储方式使用JobStoreTX 也就是数据库 LocalDataSourceJobStore
|
||||
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
|
||||
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
|
||||
# 表名前缀
|
||||
|
|
|
@ -46,6 +46,5 @@
|
|||
and job_method_name like CONCAT('%',#{dto.jobMethodName},'%')
|
||||
</if>
|
||||
</where>
|
||||
order by update_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cn.bunny.services.service.impl;
|
||||
|
||||
import cn.bunny.services.aop.AnnotationScanner;
|
||||
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@SpringBootTest
|
||||
class SchedulersServiceImplTest {
|
||||
|
||||
@Autowired
|
||||
private AnnotationScanner annotationScanner;
|
||||
|
||||
@Test
|
||||
void getAllJobClass() {
|
||||
Set<Class<?>> classesWithAnnotation = annotationScanner.getClassesWithAnnotation(QuartzSchedulers.class);
|
||||
classesWithAnnotation.forEach(cls -> {
|
||||
String classReference = cls.getName();
|
||||
String description = cls.getAnnotation(QuartzSchedulers.class).description();
|
||||
System.out.println(classReference);
|
||||
System.out.println(description);
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue