Job接口包含什么
Job接口非常容易实现,它只有一个execute方法。从上篇文章可以了解到这个方法中有一个JobExecutionContext参数,它保存着当前Job的所有信息。
JobDetail用来干什么
当你实现Job接口类,Quartz需要你提供job实例的各种参数,Job接口实现类中的代码才知道如何去完成指定类型Job的实际工作。这个过程是通过JobDetail类来完成的。(以下代码可以在后续Springboot2.0整合Quartz中找到)
//创建一个新的job任务
@GetMapping("/add/{jobName}")
public void addJob(@PathVariable(value = "jobName") String jobName) {
String groupName = "group_one"; //定义job所在组名称
String cronExpression = "0 * * * * ? *";//执行时间表达式
try {
//构建一个新的任务规范,执行特定任务,任务执行的时间
JJobDetail jobDetail = JobBuilder.newJob(SampleJob.class).withIdentity(jobName, groupName)
.usingJobData("jobSays", "Hello World!")
.build();
//执行的任务中传入参数
jobDetail.getJobDataMap().put("jobname", jobName);
//创建corn表达式,创建执行任务的时间规范
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//创建一个触发器,加入上面创建的时间规范
CronTrigger trigger =
TriggerBuilder.newTrigger().withIdentity(jobName, groupName).withSchedule(scheduleBuilder)
.build();
//把执行的job任务和创建时间trigger绑定一起
scheduler.scheduleJob(jobDetail, trigger);
//启动任务调度器,准备添加任务相关信息操作
scheduler.start();
} catch (SchedulerException e) {
LOGGER.info("scheduler start or shutdown error ...");
}
}
下面是任务SampleJob.class
public class SampleJob implements Job {
@Autowired
@Qualifier(value = "Scheduler")
private Scheduler scheduler;
public SampleJob() {
}
@Override
public void execute(JobExecutionContext context) {
String id = context.getJobDetail().getJobDataMap().get("jobname").toString();
id = id + ">";
System.out.println("执行方法。。。。。" + id);
context.getJobDetail().getJobDataMap().put("jobname", id);
try {
scheduler.addJob(context.getJobDetail(), true, true);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
从上面代码可以注意到我们给scheduler提供了一个JobDetail实例,我们构建JobDetail对象时不仅提供了job的class对象,还定义了JobKey,并且通过JobDataMap为Job传递参数。调度器就知道它要执行的job类型。每次调度器执行job时,它在调用excecute方法前会创建一个新的job实例,同时将传递的参数作为实例参数,以便于我们后续跟踪状态。
JobDataMap的作用
JobDataMap是JobDetail的一部分
- 为Job传入参数
JobDataMap可以用来持有任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。JobDataMap实现Map接口,并且添加了一些非常方便的方法用来存取基本数据类型。
下面的代码片断演示了在定义/构建JobDetail对象时,job对象添加到调度器之前,如何将数据存放至JobDataMap中:
//构建一个新的任务规范,执行特定任务,任务执行的时间
JobDetail jobDetail = JobBuilder.newJob(SampleJob.class).withIdentity(jobName, groupName)
.usingJobData("jobSays", "Hello World!") // 1.使用usingJobData直接赋值
.build();
//执行的任务中传入参数
jobDetail.getJobDataMap().put("jobname", jobName); // 2.先获取JobDataMap,然后再填入参数
- 在Job中获取传递的参数
我们可以从Job的JobExecutionContext中获取JobDetail,然后获取JobDataMap,最后从JobDataMap中按键取出参数内容。
@Override
public void execute(JobExecutionContext context) {
String id = context.getJobDetail().getJobDataMap().get("jobname").toString();
id = id + ">";
System.out.println("执行方法。。。。。" + id);
}
Job实例
你可以创建一个单独的Job实现类,创建多个不同的JobDetail实例,将不同Job实例定义存储在调度器中,每个JobDetail实例都有各自的参数和JobDataMap,并且把这些JobDetail添加到调度器中。
例如:你创建一个Job接口的实现类,类名为“SalesReportJob”,Job类可以预先传入一些假想的参数(通过JobDataMap)来指定销售报表中业务员的名字。接下来创建多个Job的定义(即JobDetail),如“SalesReportForJoe”和 “SalesReportForMike”通过“Joe”和“Mike”指定到相应的JobDataMap中作为参数输入到各自的Job对象中。
当trigger被触发时,相关的JobDetail实例会被加载,通过在调度器中配置的JobFactory会将关联的Job类实例化。默认的JobFactory只是简单的调用Job类的newInstance方法,然后尝试调用匹配JobDataMap键值的setter方法。你可以开创建自己的JobFactory实现类,以完成一些诸如通过应用IOC或DI机制完成Job实例的创建和初始化的事情。
用Quartz框架的话来说,我们将每个存储的JobDetail称为Job定义或JobDetail实例,将每个执行的作业任务(Job)称为Job实例或Job定义实例。通常我们只用“job”单词来对应命名的Job定义或是JobDetail。当我们指Job接口的实现类时,一般使用“job class”术语。
上一篇:Quartz简单使用以及常用API解释
下一篇:Quartz Trigger详解
评论区