quartz是在java语言中用得最为广泛的任务调度框架,spring对quartz进行了集成,方便了开发和使用。
在springboot下,我们对一个采用quartz的app进行多个集群部署的时候,对于quartz的集群采用数据库集群方式,报了“MethodInvokingJobDetailFactoryBean is not serializable”的错误。
原因是spring为了让开发更方便,耦合性更低,对quartz中 JobDetailFactoryBean 用 MethodInvokingJobDetailFactoryBean 进行了封装,假如quartz是单机运行那是没有关系的,但是当采用数据库方式进行集群的时候,quartz会把 JobDetailFactoryBean 序列化存储到数据库中,假如用 MethodInvokingJobDetailFactoryBean 的话,就会报错,说不能序列化。
解决的办法参考这篇文章:使用Spring + quartz集群持久化时注意事项,但是这篇文章中只讲了在spring下如何修改。
下面讲一下在 springboot 中如何修改:
一、需要将原先定义的pojo 的 Job 改成实现 Job 接口:
@Component("myJobHandler")
public class MyJobHandler implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("do it ......");
}
}
二、在配置中如下设置:
@Bean(name = "myJobDetailFactoryBean")
public JobDetailFactoryBean getMyJobDetailFactoryBean() {
JobDetailFactoryBean jobDetail = new JobDetailFactoryBean();
jobDetail.setJobClass(com.champbay.quartztest.MyJobHandler.class);
jobDetail.setDurability(true);
return jobDetail;
}
@Bean(name = "myCronTriggerFactoryBean")
public CronTriggerFactoryBean getMyCronTriggerFactoryBean(
@Qualifier("myJobDetailFactoryBean") JobDetailFactoryBean jobDetail) {
CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
tigger.setJobDetail(jobDetail.getObject());
// 每1分钟
tigger.setCronExpression("0 0/1 * * * ?");
return tigger;
}
本文结束。