spring boot中使用quartz時的問題

在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沒有報錯了,代碼也可以正常運行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章