SpringBoot整合quartz(支持多个任务和job支持spring管理的对象)

工作中经常遇到quartz的job注入的spring对象为null,原因是这样的:quartz每次执行一次job会将执行完成后的job销毁,下次执行的时候,重新new,这就导致job中的@Autowired注入的Spring对象为null,下面为了避免这个问题,以后的job都是从spring中获取。之前的文章只适合单个的job,这次采用Factory的方式,支持多个job。

上代码:

1、创建一个SchedulerListener类,并实现ApplicationListener,并编写自己的schedulerFactoryBean

@Configuration
public class MySchedulerListener implements ApplicationListener {

	@Autowired
	MyScheduler myScheduler;
	
	@Autowired
	MyJobFactory myJobFactory;
	
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		try {
			myScheduler.schedulerJob();
			System.out.println("SynchronizedData job  start...");
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	@Bean(name ="mySchedulerFactoryBean")
	public SchedulerFactoryBean mySchedulerFactory() {
		SchedulerFactoryBean bean = new SchedulerFactoryBean();
		bean.setOverwriteExistingJobs(true);
		bean.setStartupDelay(1);
		bean.setJobFactory(myJobFactory);
		return bean;
	}

}
2、重新AdaptableJobFactory工厂,从spring获得bean(这个是很重要的)
@Component
public class MyJobFactory extends AdaptableJobFactory {
    
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
3、编写job

job1

public class MySchedulerJob implements Job {

	private SimpleDateFormat dateFormat() {
		return new SimpleDateFormat("HH:mm:ss");
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		System.out.println("AAAA: The time is now " + dateFormat().format(new Date()));
	}

}

job2

public class MySchedulerJob2 implements Job {

	@Autowired
	NoticeTemplateService noticeTemplateService;//这个service为spring管理的对象,service可自由编写
	
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		List> result = noticeTemplateService.getOverTimeActionIdAndEventId();
		int l = result.size();
		System.out.println("SchedulerJob2 event number: "+l);
	}

}

4、编写Scheduler,并添加job

@Component
public class MyScheduler {


	public void schedulerJob() throws SchedulerException {
		ApplicationContext annotationContext = SpringUtil.getApplicationContext();
		StdScheduler stdScheduler = (StdScheduler) annotationContext.getBean("mySchedulerFactoryBean");//获得上面创建的bean
		Scheduler myScheduler =stdScheduler;
		startScheduler1(myScheduler);
		startScheduler2(myScheduler);
		myScheduler.start();
	}

	public void startScheduler1(Scheduler scheduler) throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(MySchedulerJob.class).withIdentity("job1", "jobGroup1").build();
		CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
				.withSchedule(cronScheduleBuilder).build();
		scheduler.scheduleJob(jobDetail, trigger);
	}
	
	public void startScheduler2(Scheduler scheduler) throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(MySchedulerJob2.class).withIdentity("job2", "jobGroup2").build();
		CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "triggerGroup2")
				.withSchedule(cronScheduleBuilder).build();
		scheduler.scheduleJob(jobDetail, trigger);

	}

}

5、SpringUtil获得application

@Component
public class SpringUtil implements ApplicationContextAware {

	private static final Logger logger = LoggerFactory.getLogger(SpringUtil.class);

	private static ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		if (SpringUtil.applicationContext == null) {
			SpringUtil.applicationContext = applicationContext;
		}
		logger.info("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getApplicationContext()获取applicationContext对象,applicationContext="
						+ SpringUtil.applicationContext + "========");
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	// 通过name获取 Bean.
	@SuppressWarnings("unchecked")
	public static  T getBean(String name) {
		return (T) getApplicationContext().getBean(name);
	}

	// 通过class获取Bean.
	public static  T getBean(Class clazz) {
		return getApplicationContext().getBean(clazz);
	}

	// 通过name,以及Clazz返回指定的Bean
	public static  T getBean(String name, Class clazz) {
		return getApplicationContext().getBean(name, clazz);
	}

}


运行即可。


你可能感兴趣的:(java)