1. 抽象实体类
@Data
public class AbstractEntity implements Serializable {
@TableId ( type = IdType . UUID)
private String id;
private String createBy;
private Date createDate;
private String updateBy;
private Date updateDate;
}
2. 定时任务实体类
package com. len. entity ;
import com. baomidou. mybatisplus. annotation. IdType ;
import com. baomidou. mybatisplus. annotation. TableField ;
import com. baomidou. mybatisplus. annotation. TableId ;
import com. baomidou. mybatisplus. annotation. TableName ;
import com. len. base. AbstractEntity ;
import com. len. validator. group. AddGroup ;
import com. len. validator. group. UpdateGroup ;
import lombok. Data ;
import lombok. EqualsAndHashCode ;
import lombok. ToString ;
import javax. validation. constraints. NotEmpty ;
import java. util. Date ;
@EqualsAndHashCode ( callSuper = true )
@TableName ( value = "sys_job" )
@Data
@ToString
public class SysJob extends AbstractEntity {
@NotEmpty ( message = "任务描述不能为空" , groups = { AddGroup . class , UpdateGroup . class } )
private String jobName;
@NotEmpty ( message = "表达式不能为空" , groups = { AddGroup . class , UpdateGroup . class } )
private String cron;
private Boolean status;
@NotEmpty ( message = "执行方法不能未空" , groups = { AddGroup . class , UpdateGroup . class } )
private String clazzPath;
private String jobDesc;
}
3. 自定义JobFactory
package com. len. core. quartz ;
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
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance ( TriggerFiredBundle bundle) throws Exception {
Object job = super . createJobInstance ( bundle) ;
capableBeanFactory. autowireBean ( job) ;
return job;
}
}
4. 自定义SchedulerFactoryBean
package com. len. core. quartz ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. context. ApplicationContext ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. core. io. ClassPathResource ;
import org. springframework. scheduling. quartz. SchedulerFactoryBean ;
@Configuration
public class MySchedulerListener {
@Autowired
MyJobFactory myJobFactory;
@Bean ( name = "schedulerFactoryBean" )
public SchedulerFactoryBean schedulerFactory ( ) {
SchedulerFactoryBean bean = new SchedulerFactoryBean ( ) ;
bean. setJobFactory ( myJobFactory) ;
bean. setConfigLocation ( new ClassPathResource ( "quartz.properties" ) ) ;
return bean;
}
}
5. quartz.properties
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 20
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
6. 定时任务操作类
package com. len. core. quartz ;
import com. len. entity. SysJob ;
import lombok. extern. slf4j. Slf4j ;
import org. apache. commons. lang3. time. DateFormatUtils ;
import org. quartz. * ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. scheduling. quartz. SchedulerFactoryBean ;
import org. springframework. stereotype. Service ;
import java. util. Date ;
import java. util. HashSet ;
@Service
@Slf4j
public class JobTask {
@Autowired
SchedulerFactoryBean schedulerFactoryBean;
public boolean checkJob ( SysJob job) {
Scheduler scheduler = schedulerFactoryBean. getScheduler ( ) ;
TriggerKey triggerKey = TriggerKey . triggerKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ;
try {
if ( scheduler. checkExists ( triggerKey) ) {
return true ;
}
} catch ( SchedulerException e) {
e. printStackTrace ( ) ;
}
return false ;
}
public boolean startJob ( SysJob job) throws ClassNotFoundException , SchedulerException {
Scheduler scheduler = schedulerFactoryBean. getScheduler ( ) ;
Class clazz = Class . forName ( job. getClazzPath ( ) ) ;
JobDetail jobDetail = JobBuilder . newJob ( clazz) . build ( ) ;
TriggerKey triggerKey = TriggerKey . triggerKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ;
CronTrigger trigger = TriggerBuilder . newTrigger ( ) . withIdentity ( triggerKey)
. withSchedule ( CronScheduleBuilder . cronSchedule ( job. getCron ( ) ) ) . build ( ) ;
scheduler. scheduleJob ( jobDetail, trigger) ;
if ( ! scheduler. isShutdown ( ) ) {
scheduler. start ( ) ;
log. info ( "---任务[" + triggerKey. getName ( ) + "]启动成功-------" ) ;
return true ;
} else {
log. info ( "---任务[" + triggerKey. getName ( ) + "]已经运行,请勿再次启动-------" ) ;
}
return false ;
}
public boolean updateJob ( SysJob job) {
Scheduler scheduler = schedulerFactoryBean. getScheduler ( ) ;
String createTime = DateFormatUtils . format ( new Date ( ) , "yyyy-MM-dd HH:mm:ss" ) ;
TriggerKey triggerKey = TriggerKey . triggerKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ;
try {
if ( scheduler. checkExists ( triggerKey) ) {
return false ;
}
JobKey jobKey = JobKey . jobKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ;
CronScheduleBuilder schedBuilder =
CronScheduleBuilder . cronSchedule ( job. getCron ( ) ) . withMisfireHandlingInstructionDoNothing ( ) ;
CronTrigger trigger = TriggerBuilder . newTrigger ( ) . withIdentity ( triggerKey) . withDescription ( createTime)
. withSchedule ( schedBuilder) . build ( ) ;
JobDetail jobDetail = scheduler. getJobDetail ( jobKey) ;
HashSet < Trigger > triggerSet = new HashSet < > ( ) ;
triggerSet. add ( trigger) ;
scheduler. scheduleJob ( jobDetail, triggerSet, true ) ;
log. info ( "---任务[" + triggerKey. getName ( ) + "]更新成功-------" ) ;
return true ;
} catch ( SchedulerException e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e. getMessage ( ) ) ;
}
}
public boolean remove ( SysJob job) {
Scheduler scheduler = schedulerFactoryBean. getScheduler ( ) ;
TriggerKey triggerKey = TriggerKey . triggerKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ;
try {
if ( checkJob ( job) ) {
scheduler. pauseTrigger ( triggerKey) ;
scheduler. unscheduleJob ( triggerKey) ;
scheduler. deleteJob ( JobKey . jobKey ( job. getId ( ) , Scheduler . DEFAULT_GROUP) ) ;
log. info ( "---任务[" + triggerKey. getName ( ) + "]删除成功-------" ) ;
return true ;
}
} catch ( SchedulerException e) {
e. printStackTrace ( ) ;
}
return false ;
}
}
7. 定时任务入口类
package com. len. controller ;
import com. len. core. quartz. JobTask ;
import org. apache. commons. lang3. StringUtils ;
import org. springframework. stereotype. Controller ;
import org. springframework. ui. Model ;
import org. springframework. web. bind. annotation. GetMapping ;
import org. springframework. web. bind. annotation. PostMapping ;
import org. springframework. web. bind. annotation. RequestMapping ;
import org. springframework. web. bind. annotation. ResponseBody ;
import com. len. base. BaseController ;
import com. len. entity. SysJob ;
import com. len. exception. ServiceException ;
import com. len. service. JobService ;
import com. len. util. LenResponse ;
import com. len. util. MsHelper ;
import com. len. util. ReType ;
import io. swagger. annotations. Api ;
import io. swagger. annotations. ApiOperation ;
@Controller
@RequestMapping ( "/job" )
@Api ( value = "定时任务" , tags = "定时任务" )
public class JobController extends BaseController < SysJob > {
private final JobService jobService;
private final JobTask jobTask;
public JobController ( JobService jobService,
JobTask jobTask) {
this . jobService = jobService;
this . jobTask = jobTask;
}
@GetMapping ( value = "showJob" )
public String showUser ( Model model) {
return "/system/job/jobList" ;
}
@GetMapping ( value = "showJobList" )
@ResponseBody
public ReType showUser ( SysJob job, String page, String limit) {
return jobService. show ( job, Integer . parseInt ( page) , Integer . parseInt ( limit) ) ;
}
@GetMapping ( value = "showAddJob" )
public String addJob ( ) {
return "/system/job/add" ;
}
@ApiOperation ( value = "/addJob" , httpMethod = "POST" , notes = "添加任务类" )
@PostMapping ( value = "addJob" )
@ResponseBody
public LenResponse addJob ( SysJob job) {
job. setStatus ( false ) ;
jobService. save ( job) ;
return succ ( MsHelper . getMsg ( "insert.success" ) ) ;
}
@GetMapping ( value = "updateJob" )
public String updateJob ( String id, Model model, boolean detail) {
if ( StringUtils . isNotEmpty ( id) ) {
SysJob job = jobService. getById ( id) ;
model. addAttribute ( "job" , job) ;
}
model. addAttribute ( "detail" , detail) ;
return "system/job/update" ;
}
@ApiOperation ( value = "/updateJob" , httpMethod = "POST" , notes = "更新任务" )
@PostMapping ( value = "updateJob" )
@ResponseBody
public LenResponse updateJob ( SysJob job) {
if ( jobTask. checkJob ( job) ) {
throw new ServiceException ( MsHelper . getMsg ( "job.started" ) ) ;
}
jobService. updateJob ( job) ;
return succ ( MsHelper . getMsg ( "update.success" ) ) ;
}
@ApiOperation ( value = "/del" , httpMethod = "POST" , notes = "删除任务" )
@PostMapping ( value = "del" )
@ResponseBody
public LenResponse del ( String id) {
jobService. del ( id) ;
return succ ( MsHelper . getMsg ( "del.success" ) ) ;
}
@PostMapping ( value = "startJob" )
@ResponseBody
public LenResponse startJob ( String id) {
jobService. startJob ( id) ;
return succ ( "job.start" ) ;
}
@PostMapping ( value = "endJob" )
@ResponseBody
public LenResponse endJob ( String id) {
jobService. stopJob ( id) ;
return succ ( MsHelper . getMsg ( "job.stop" ) ) ;
}
}