好久没更新了,因为感觉没什么可写的·····
这是基于spring boot的quartz 定时任务简单实现。
1、Controller代码
@Controller
@RequestMapping("/time")
public class TimeController {
private final static String GROUPNAME = "MyJob";
private static Long testId = new Long(1);
@PostConstruct
public void init() throws SchedulerException {
System.out.println("logalert_init start");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
addQuartzJob(testId, "localSystemName", "env", "0/5 * * * * ?");
scheduler.start();
System.out.println("logalert_init end");
}
private static void executeOneQuartzJob(Long id, String localSystemName, String env) {
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity(id+"",GROUPNAME).usingJobData("id", id).build();
SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity(id+"",GROUPNAME).startAt(new Date()).build();
// scheduler.addJob(jobDetail, true);
scheduler.scheduleJob(jobDetail, simpleTrigger);
// scheduler.start();
// Thread.sleep(5000);
//
// TriggerKey triggerKey = TriggerKey.triggerKey(localSystemName + "_" + env + "_" + id, GROUPNAME);
//
// scheduler.pauseTrigger(triggerKey);// 停止触发器
// scheduler.unscheduleJob(triggerKey);
// JobKey jobKey = JobKey.jobKey(localSystemName + "_" + env + "_" + id, GROUPNAME);
// scheduler.deleteJob(jobKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Scheduled(fixedRate = 5000)
public void flush() throws SchedulerException {
System.out.println("flush start");
addQuartzJob(++testId, "localSystemName", "env", "0/5 * * * * ?");
System.out.println("flush end:"+testId);
}
private static void addQuartzJob(Long id, String localSystemName, String env, String corntabEx) {
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity(id+"",GROUPNAME).usingJobData("id", id).build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(id+"",GROUPNAME)
.withSchedule(CronScheduleBuilder.cronSchedule(corntabEx)).build();
scheduler.scheduleJob(jobDetail, cronTrigger);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void removeQuartzJob(Long id) {
try {
String jobName = id+"";
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, GROUPNAME);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);
JobKey jobKey = JobKey.jobKey(jobName, GROUPNAME);
scheduler.deleteJob(jobKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
当 Scheduler 决定了是时候运行 Job 时,方法 execute() 就会被调用,并传递一个 JobExecutionContext 对象给这个 Job。
当 Scheduler 调用一个 Job,一个 JobexecutionContext 传递给 execute() 方法。JobExecutionContext 对象让 Job 能访问 Quartz 运行时候环境和 Job 本身的明细数据。
角色 SchedulerFactory 就是用来产生
Scheduler 实例的。当 Scheduler 实例被创建之后,就会存到一个仓库中(org.quartz.impl.SchedulerRepository),这个仓库还提供了通过一个 class loader 查询实例的机制。要使用 Scheduler 实例,客户端必须从工厂(和随同的仓库中)使用不同方法调用来获取到它们。
Trigger(触发器)的责任就是触发一个 Job 去执行。当用 Scheduler 注册一个 Job 的时候要创建一个 Trigger 与这个 Job 相关联。
SimpleTrigger 是两个之中简单的那个,它主要用来激发单事件的 Job,Trigger 在指定时间激发,并重复 n 次--两次激发时间之间的延时为
m,然后结束作业。
CronTrigger 非常复杂且强大。它是基于通用的公历,当需要用一种较复杂的时间表去执行一个 Job 时用到。
这两个触发器以上代码都已用到。
public class MyJob implements Job {
// @Autowired
// private MyService myService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Long id = (Long) context.getMergedJobDataMap().get("id");
System.out.println("MyJob id is "+id);
// String back = myService.getFromService(id);
MyService myService = SpringBeanFactory.getBean(MyService.class);
String back = myService.getFromService(id);
System.out.println("from Service:"+back);
}
}
3、service的实现类
@Service
public class MyServiceImpl implements MyService {
@Override
public String getFromService(Long id){
return "hello:"+id;
}
}
4、启动类
注意一定要有@EnableScheduling注解否则会抛出异常,具体的异常忘了·······
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
5、如果你的项目使用了maven,那么恭喜你
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
6、我所遇到的坑:
@PostConstruct 使用这个注解的方法只会执行一次,在bean实例化之前执行,而我在这个方法里
做了这事:scheduler.start();
也就是启动定时任务,
而myJob里会调用myservice,如果使用@Autowired的方法获得myservice,就会抛出空值的问题。
所以需要使用getBean的方法获得bean实例。
最后贴上获取bean的代码:
@Component
public class SpringBeanFactory implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 获取某个Bean的对象
*/
public static <T> T getBean(Class<T> clazz) {
try {
return applicationContext.getBean(clazz);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
刚刚接触,如有错误,还请各位大佬指出错误。
博客不定时更新·········