转自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;
}
}
|