在spring boot中使用quartz,参考了文章springboot整合quartz,由于我使用的是IntelliJ IDEA,在注解Trigger bean的时候,IDE显示“Could not autowire.No Beans of "MethodInvokingJobDetailFactoryBean" type found”.网上也查找了很多资料,都说这个错是IDE的问题,把autowired的检查级别从error改到warning,事实上如果忽略的话功能也确实可以使用。但是IDE既然默认把它设成error级别肯定也是有它的道理的。经过我的研究,由这个问题引申出两个知识点。
1.bean与bean之间的关系
2.factorybean和bean的关系
先帖上相关代码
@Configuration
public class QuartzConfiguration {
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(CalUshimataTask task){
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
jobDetail.setConcurrent(false);
jobDetail.setName("cal-ushimata");
jobDetail.setGroup("ushimata");
jobDetail.setTargetObject(task);
jobDetail.setTargetMethod("doJob");
return jobDetail;
}
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail){
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(jobDetail.getObject());
trigger.setCronExpression("0/5 * * * * ?");
trigger.setName("cal-ushimata");
return trigger;
}
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory(Trigger cronTrigger){
SchedulerFactoryBean bean = new SchedulerFactoryBean();
bean.setOverwriteExistingJobs(true);
bean.setStartupDelay(1);
bean.setTriggers(cronTrigger);
return bean;
}
}
首先我们来看
1.bean与bean之间的关系
bean与bean之间的关系分为继承,依赖和引用三种,注解的方法和参数bean之间属于依赖的关系,参数bean需要先于方法bean初始化。
2.factorybean和bean的关系
factorybean是bean的工厂类,bean是通过factorybean生产出来的。那使用factorybean有什么好处呢?某些情况下,实例化bean的过程会比较复杂,所以Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑,Spring自身就提供了70多个FactoryBean的实现。通过factorybean的getObject()方法获取到生产的bean对象,重要的一点,factorybean实例化的时候getBean("id")方法得到的不是它本身,而是通过它生产的对象。关于这个的原理请查看一下FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法。
好啦,搞清楚了上面两点,我们得到的结论是由于MethodInvokingJobDetailFactoryBean和cronJobTrigger之间是依赖的关系,MethodInvokingJobDetailFactoryBean需要先实例化,MethodInvokingJobDetailFactoryBean实例化返回的是JobDetail对象,因此我的解决方案如下:
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(JobDetail jobDetail){
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(jobDetail);
trigger.setCronExpression("0/5 * * * * ?");
trigger.setName("cal-ushimata");
return trigger;
}
IDE没有报错了,代码也可以正常运行。