關於Spring boot框架整合quartz,解決了mapper無法注入的問題


轉自https://blog.csdn.net/shasiqq/article/details/80421479

https://blog.csdn.net/li614814/article/details/80543515

我只貼代碼:

1.配置pom.xml

<dependency>
     <groupId>org.quartz-scheduler</groupId>
     <artifactId>quartz</artifactId>
     <version>2.2.1</version>
</dependency>
<dependency><!-- 該依賴必加,里面有sping對schedule的支持 -->
     <groupId>org.springframework</groupId>
     <artifactId>spring-context-support</artifactId>
</dependency>

2.先寫一個監聽器保證項目啟動的時候會調用到,我們的定時任務,代碼如下

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;

import com.fjaidata.timer.MyScheduler;

@Configuration
public class SchedulerListener implements ApplicationListener<ContextRefreshedEvent>{
    @Autowired
    public MyScheduler myScheduler;
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
            myScheduler.scheduleJobs();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

}

3.寫我們自己的定時器,用來觸發我們的任務

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import com.fjaidata.job.AiArticleJob;
import com.fjaidata.job.SealedBiddingJob;
@Component
public class MyScheduler {
    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    static Scheduler scheduler;

    public void scheduleJobs() throws SchedulerException {
        scheduler = schedulerFactoryBean.getScheduler();
        startJob1();
        startJob2();
    }
    
    public static void startJob1() throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(AiArticleJob.class).withIdentity("job1", "group1").build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 8 * * ?");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
    
    public static void startJob2() throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(SealedBiddingJob.class).withIdentity("job2", "group1").build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 8 ? * MON,FRI");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1")
                .withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
    
    
}

4.定時器

@Configuration
public class SealedBiddingJob implements Job{
    @Autowired
    private SealedBiddingMapper biddingMapper;
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {}
}

這是我們會發現總是報空指針的問題

原因:在quartz框架中,Job 是通過反射出來的實例,不受spring的管理。Scheduler現在交給Spring生成,在Spirng-context-support  jar包下org.springframework.scheduling.quartz包中有個SpringBeanJobFactory的類,job實例通過該類的createJobInstance方法創建。根據Scheduler context、job data map and trigger data map填充其屬性。但是創建的job實例並沒被spring管理,這就需要我們自定義一個類將創建的job添加到applicationContext中,該類需要繼承SpringBeanJobFactory,並實現ApplicationContextAware接口。

    ApplicationContextAware接口的作用:Spring容器會檢測容器中的所有Bean,如果發現某個Bean實現了ApplicationContextAware接口,Spring容器會在創建該Bean之后,自動調用該Bean的setApplicationContextAware()方法,調用該方法時,會將容器本身作為參數傳給該方法——該方法中的實現部分將Spring傳入的參數(容器本身)賦給該類對象的applicationContext實例變量,因此接下來可以通過該applicationContext實例變量來訪問容器本身。

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
        ApplicationContextAware {

    private transient AutowireCapableBeanFactory autowireCapablebeanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        autowireCapablebeanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        autowireCapablebeanFactory.autowireBean(job);
        return job;
    }
}
@Configuration
public class SchedulerConfig {
    
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext)
    {
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws Exception {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setOverwriteExistingJobs(true);
        factory.setJobFactory(jobFactory);
        factory.afterPropertiesSet();
        return factory;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM