Spring Boot 定时任务四 :SpringBoot整合Quartz

通过上一篇,我们知道quartz的使用只需要3步,而springboot整合Quartz其实就是实现此3个步骤。

一、pom文件新增jar

<!-- Sprng tx 坐标-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
		</dependency>

二、定时任务

   沿用上一篇的任务文件MyJob.java

三、创建Quartz的配置文件

    此文件其实就是实现Quartzding定时任务的三个步骤。

@Configuration
public class QuartzConfig {
	/**
	* 1.创建Job 对象
	*/
	@Bean
	public JobDetailFactoryBean jobDetailFactoryBean(){
		JobDetailFactoryBean factory = new JobDetailFactoryBean();
		//关联我们自己的Job 类
		factory.setJobClass(MyJob.class);
		return factory;
	}
	/**
	* 2.创建Trigger 对象
	*/
	@Bean
	public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
		CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
		factory.setJobDetail(jobDetailFactoryBean.getObject());
		//设置触发时间
		factory.setCronExpression("0/2 * * * * ?");
		return factory;
	}
	/**
	* 3.创建Scheduler 对象
	*/
	@Bean
	public SchedulerFactoryBean	schedulerFactoryBean(CronTriggerFactoryBean triggerFactoryBean){
		SchedulerFactoryBean factory = new SchedulerFactoryBean();
		//关联trigger
		factory.setTriggers(triggerFactoryBean.getObject());
		return factory;
	}
}

四、运行结果

    执行Springboot的启动文件,控制台的运行结果如下,可以看出每隔2秒执行一次任务

五、模拟服务层 UserService

     在现实场景下,定时任务中肯定是需要调用服务层的功能,那么就要将服务层注入到任务中。

     这里做个简单的模拟,新增一个用户功能

@Service
public class UserService {
	public void addUser() {
		System.out.println("**>addUser");
	}
}

六、注入service

在定时任务zh中注入service

@Autowired
	UserService userService;
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		this.userService.addUser();
		System.out.println("任务-->"+new Date());
	}

运行后,控制台报错如下    

这是应该注入进来的userService并没有实例化,而我们的MyJob的实例化是通过Job对象中的JobDetailFactoryBean来实例化的,参见代码        JobDetailFactoryBean factory = new JobDetailFactoryBean();
                         //关联我们自己的Job 类
                          factory.setJobClass(MyJob.class);

而我们的定时任务的实例化是通过AdaptableJobFactory类中的createJobInstance方法实现,源码如下

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
		Class<?> jobClass = bundle.getJobDetail().getJobClass();
		return ReflectionUtils.accessibleConstructor(jobClass).newInstance();
	}

从源码可以看出,我们的类是被AdaptableJobFactory通过反射的方式来实例化,并没有被Spring实例化。那么我们只要在执行任务调度之前,将相应的对象注入到Spring MVC中即可。

七、自定义AdaptableJobFactory

      重写反射的方法createJobInstance

@Component
public class MyAdaptableJobFactory extends AdaptableJobFactory {
	// 可以将一个对象添加到SpringIOC 容器中,并且完成该对象注入
	@Autowired
	private AutowireCapableBeanFactory autowireCapableBeanFactory;
	/**
	* 该方法需要将实例化的任务对象手动的添加到springIOC 容器中并且完成对象的注入
	*/
	@Override
	protected Object createJobInstance(TriggerFiredBundle bundle)	throws Exception {
		Object obj = super.createJobInstance(bundle);
		//将obj 对象添加Spring IOC 容器中,并完成注入
		this.autowireCapableBeanFactory.autowireBean(obj);
		return obj;
	}
}

八、修改Scheduler

/**
    * 3.创建Scheduler 对象
    */
    @Bean
    public SchedulerFactoryBean    schedulerFactoryBean(CronTriggerFactoryBean triggerFactoryBean,MyAdaptableJobFactory jobFactory){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        //关联trigger
        factory.setTriggers(triggerFactoryBean.getObject());
        factory.setJobFactory(jobFactory);
        return factory;
    }

九、运行结果

猜你喜欢

转载自blog.csdn.net/zhuiyue82/article/details/87089885