pom.xml
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
Cron.java // 注解:扫描知道哪个是处理定时任务的类
package org.example.testquartz;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Cron {
}
Schedule.java // 知道定时任务详情表达式
package org.example.testquartz;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedule {
String value();
}
QuartzJob.java // 具体执行的定时任务,通过自定义参数如data0
// 这个可以区分不同的定时任务,比如:有的要求发邮件
package org.example.testquartz;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.lang.reflect.Method;
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
// 这里是只有一个data0,还可以定义不同的参数进来
// 如:定时发邮件的,会有哪个人这个参数
Method method = (Method) jobDataMap.get("data0");
method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
CronTab.java // 指定具体的任务逻辑
package org.example.testquartz;
@Cron
public class CronTab {
@Schedule(value = "0/3 0-59 16 * * ?")
public static void execEvery3Second() {
System.out.println("execEvery3Second call once=" + System.currentTimeMillis() + "=" + Thread.currentThread().getName());
}
@Schedule(value = "0/5 0-59 16 * * ?")
public static void execEvery5Second() {
System.out.println("execEvery5Second call once=" + System.currentTimeMillis() + "=" + Thread.currentThread().getName());
}
}
/*
execEvery3Second call once=1633939758004=DefaultQuartzScheduler_Worker-1
execEvery5Second call once=1633939760003=DefaultQuartzScheduler_Worker-2
execEvery3Second call once=1633939761013=DefaultQuartzScheduler_Worker-3
execEvery3Second call once=1633939764009=DefaultQuartzScheduler_Worker-4
execEvery5Second call once=1633939765013=DefaultQuartzScheduler_Worker-5
execEvery3Second call once=1633939767004=DefaultQuartzScheduler_Worker-6
execEvery5Second call once=1633939770013=DefaultQuartzScheduler_Worker-7
execEvery3Second call once=1633939770013=DefaultQuartzScheduler_Worker-8
execEvery3Second call once=1633939773009=DefaultQuartzScheduler_Worker-9
execEvery5Second call once=1633939775001=DefaultQuartzScheduler_Worker-10
execEvery3Second call once=1633939776006=DefaultQuartzScheduler_Worker-1
*/
MethodManager.java // 初始化quartz 扫描有哪些定时任务
package org.example.testquartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.reflections.Reflections;
import java.lang.reflect.Method;
import java.util.*;
public class MethodManager {
public static MethodManager INSTANCE = new MethodManager();
private Scheduler scheduler;
private Map<Class<?>, List<Method>> methodMap = new HashMap<>();
public void init() {
// 开启
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
// 扫描类,创建最普通的定时任务
Reflections reflections = new Reflections("org");
Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(Cron.class);
typesAnnotatedWith.forEach(c -> {
Method[] declaredMethods = c.getDeclaredMethods();
List<Method> list = new ArrayList<>();
for (Method method : declaredMethods) {
if (method.isAnnotationPresent(Schedule.class)) {
Schedule schedule = method.getAnnotation(Schedule.class);
// 这里只是创建QuartzJob这种类型的job,还可以扩展出发邮件等的Job
createJob("QuartzJob" + method.hashCode(), schedule.value(), QuartzJob.class, method);
}
}
});
}
public void createJob(String jobName, String cronExpression, Class jobClass, Object... data) {
try {
JobKey jobKey = new JobKey(jobName, Scheduler.DEFAULT_GROUP);
if (scheduler.getJobDetail(jobKey) != null) {
scheduler.deleteJob(jobKey);
}
JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobKey).build();
// 设置好附加参数,在回调时使用
for (int i = 0; i < data.length; i++) {
job.getJobDataMap().put("data" + i, data[i]);
}
TriggerKey triggerKey = new TriggerKey(jobName, Scheduler.DEFAULT_GROUP);
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity(triggerKey)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
.build();
scheduler.scheduleJob(job, trigger);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Main.java //入口类
package org.example.testquartz;
public class Main {
public static void main(String[] args) {
MethodManager.INSTANCE.init();
}
}
总结:
可见默认的定时任务读取quartz下的配置文件,默认是10个线程,任务到了后依次执行。
这里的例子是:启动时就创建好的定时任务,当然是支持动态创建的,通过createJob方法,如:定时发送邮件,则直接扔进去即可,同时可以根据附加的参数,到了后,就可以知道比如:是给谁发送什么邮件都是可以支持的。