背景
继上一篇 通过quartz 灵活的设置我们需要时间的定时任务,这一篇是上一篇的延续,通过传入的时间设置闹钟
可用在不确定时间的计划任务需求上,比如按时间表执行任务计划,传入特定的时间做提醒事项等业务需求
码云地址
https://gitee.com/yangsx123/TimingJob
代码:
controller
@Controller
public class TestController {
@Autowired
TestService testService;
@RequestMapping("/setPlan")
@ResponseBody
public String setPlan(@RequestParam String timeStr){
testService.setPlan(timeStr);
return "success";
}
}
service
@Service
public class TestService {
//任务实例
private static JobDetail jobDetail;
//调度器
private static Scheduler scheduler;
static {
try {
//1、调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)
scheduler = StdSchedulerFactory.getDefaultScheduler();
//2、任务实例(JobDetail)
jobDetail = JobBuilder.newJob(DoDefenceJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
.withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称
.build();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 执行实际的业务代码
*/
public void doTask(){
System.out.println("闹钟响了");
}
/**
* 设置定时任务计划
*/
public void setPlan(String timeStr) {
try {
//清理完scheduler里面的任务
//scheduler.clear();
String timeStrCron = toCron(timeStr);
//创建触发器
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule(timeStrCron))
.build();
//将任务及其触发器放入调度器
scheduler.scheduleJob(jobDetail, trigger);
//调度器开始调度任务
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 具体时间转换成cron
*
* @param dateStr 2022-03-31 09:51:05
* @return
*/
public static String toCron(String dateStr) {
LocalDateTime time = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String cronStr = time.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));
return cronStr;
}
}
SpringContext – 获取spring的上下文对象用
@Component
public class SpringContext implements ApplicationContextAware {
/**
* 打印日志
*/
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 获取上下文对象
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContext.applicationContext = applicationContext;
logger.info("set applicationContext");
}
/**
* 获取 applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过 name 获取 bean 对象
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过 class 获取 bean 对象
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过 name,clazz 获取指定的 bean 对象
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
DoDefenceJob --任务计划
@Service
@DependsOn("springContext")
public class DoDefenceJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//输出当前时间
Date date=new Date();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString=dateFormat.format(date);
//由于这个实例是通过反射创建的 并未交由spring 托管,需要使用ApplicationContext获取到service
TestService service = getService();
service.doTask();
//工作内容
System.out.println("设置定时任务,时间是:"+dateString);
}
public TestService getService() {
return SpringContext.getBean(TestService.class);
}
}
使用演示
通过apipost请求接口
http://127.0.0.1:8081/setPlan?timeStr=2022-04-12 15:18:00
请求完成过后 我们就设置好了一个2022-04-12 15:18:00的闹钟
等到了时间点过后 我们可以看到控制台打印