我们使用Quartz时候,有时候需要在job使用一些数据,那么该如何传入呢?
我们来回顾一下job是如何运行的
我们传给scheduler一个JobDetail实例,因为我们在创建JobDetail时,将要执行的job的类名传给了JobDetail,所以scheduler就知道了要执行何种类型的job;每次当scheduler执行job时,在调用其execute(…)方法之前会创建该类的一个新的实例;执行完毕,对该实例的引用就被丢弃了,实例会被垃圾回收;这种执行策略带来的一个后果是,job必须有一个无参的构造函数(当使用默认的JobFactory时);另一个后果是,在job类中,不应该定义有状态的数据属性,因为在job的多次执行中,这些属性的值不会保留。
从运行流程,我们得知job类是不能定义属性的,因为这些属性不能保留。那我们如何给job传递一些属性或者配置呢?
答案就是使用JobDataMap,JobDataMap是JobDetail的一部分,不会被丢弃,在JobDetail的生命周期一直存在。那如何使用JobDataMap,下面来写个例子
//在创建JobDetail 的时候,我们可以创建一个JobDataMap对象,然后将我们需要传递的数据放进去,然后用JobBuilder的usingJobData方法将JobDataMap传入,有时候我们传递的参数较少,可以直接使用usingJobData直接传递,如下面的usingJobData(“msg”,“hello”)
@Bean
public JobDetail builderJobDetail(){
JobDataMap jobDataMap=new JobDataMap();
jobDataMap.put("size",1);
return JobBuilder
.newJob(BuilderJob.class)//通过class引入job类
.usingJobData("msg","hello")//传递数据给JobData
.usingJobData(jobDataMap)
.withIdentity("builderJob","builderGroup")//定义任务名称和分组
.storeDurably()//当job没有触发器绑定时,保留该job,不调用该方法,则会抛弃job
.build();
}
//在job中使用JobDataMap ,使用context的getJobDetail()获取JobDetail,然后通过getJobDataMap()即可获取到JobDataMap ,再取出我们想要的数据即可
public class BuilderJob extends QuartzJobBean {
private static final Logger logger = LoggerFactory.getLogger(QuartzTestJob.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
Object msg = jobDataMap.get("msg");
logger.info("这是一个通过Builder创建的job! jobDataMap:"+msg);
}
}