天天看點

使用SchedulerFactoryBean內建Quarz Job與Spring

大家好,又見面了,我是你們的朋友全棧君。本文介紹Quartz Job與Spring的內建。

[list]

[*]Quartz Job官網:[url]http://quartz-scheduler.org[/url]

[*]Spring官網:[url]https://spring.io[/url]

[*][b]SchedulerFactoryBean Java Doc:[/b][url]http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html[/url]

[/list]

本次內建主要用到了Spring提供的

org.springframework.scheduling.quartz.SchedulerFactoryBean,該類使得Spring application context可以建立或管理Quartz的Scheduler,包括注冊JobDetails、Calendars和Triggers等。

有了這個類,可以Retire掉org.quartz.ee.servlet.QuartzInitializerListener這個Listener。

[b][color=blue]注:這個類相容Quartz 2.1.4及以上版本,Spring 4.1及以上版本。[/color][/b]

[b]1. 例子(使用Annotation):[/b]

quartz_jobs.xml:略

quartz.properties:略

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@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;  
    }  
}           

複制

實作AdaptableJobFactory接口的JobFactory類,并重寫createJobInstance方法。

import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
@Component
public class ComponentFactory {
  
  

	@Bean
	public SchedulerFactoryBean getSchedulerFactoryBean(JobFactory myJobFactory) throws Exception {
  
  
		SchedulerFactoryBean bean = new SchedulerFactoryBean();
		bean.setJobFactory(myJobFactory);
		bean.setSchedulerName("myscheduler");
		Properties quartzProperties = new Properties();
		quartzProperties.load(this.getClass().getResourceAsStream("/quartz.properties"));
		bean.setQuartzProperties(quartzProperties);
		return bean;
	}	
}           

複制

定義bean: schedulerFactoryBean。

public class DumpJob implements Job {
  
  

	@Autowired
	private ServiceA serviceA;

	public void execute(JobExecutionContext context) throws JobExecutionException {
  
  
        assertNotNull("Service should be injected.", serviceA);
	}
}           

複制

定義一個Job,注入一個Service進行Test。

[b]2. 源碼分析:[/b]

先是SchedulerFactoryBean類:

public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBean<Scheduler>,
		BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
  
  

	// Implementation of InitializingBean interface
	@Override
	public void afterPropertiesSet() throws Exception {
  
  
		// 節選
		// Create SchedulerFactory instance...
		SchedulerFactory schedulerFactory = BeanUtils.instantiateClass(this.schedulerFactoryClass);
		initSchedulerFactory(schedulerFactory);
	}
}           

複制

首先看這個類的接口,實作了InitializingBean(該接口隻定義了一個方法,叫afterPropertiesSet(),看源碼知,SchedulerFactoryBean重寫了afterPropertiesSet()方法,在裡面做了很多事情,如:

a. 建立了SchedulerFactory

b. 建立Scheduler

c. 如果有jobFactory屬性,那麼set

d. 注冊Scheduler、Job、Trigger的監聽器listener(如果有定義的話)

e. 注冊Job和Trigger

此外,我們對于Quartz Job的參數設定,也是通過SchedulerFactoryBean類來實作的,以下是該類的一些常用屬性:

[list]

[*]public static final int DEFAULT_THREAD_COUNT = 10; 預設線程數為10。

[*]private String schedulerName; Scheduler的名字,若沒有定義則預設用bean的名稱(name)。

[*]private Resource configLocation; Quartz的配置如quartz.properties的存放位置,若是在xml中配置,則可以寫成<property name=”configLocation” value=”classpath:quartz.properties”/>。

[*]private Properties quartzProperties; 若是使用Annotation來定義bean,那麼初始化quartz.properties可以用bean.setQuartzProperties(Properties)。

[*]private JobFactory jobFactory; 注入一個JobFactory對象。

[/list]

介紹org.quartz.spi.JobFactory:

public interface JobFactory {
  
  
	Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException;
}           

複制

介紹:org.springframework.scheduling.quartz.AdaptableJobFactory:

public class AdaptableJobFactory implements JobFactory {
  
  
	protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
  
  
		return bundle.getJobDetail().getJobClass().newInstance();
	}
}           

複制

若我們生成一個類實作AdaptableJobFactory,Job在執行個體化的時候都會調用AdaptableJobFactory#createJobInstance(),在上面的自定義MyJobFactory中重寫了該方法:

a. 獲得目前的jobInstance執行個體。

b. 利用AutowireCapableBeanFactory,将job執行個體設定為auto wired bean。

AutowireCapableBeanFactory是一個繼承了BeanFactory的接口,雖然是BeanFacoty的子接口,但名氣遠沒有ListableBeanFactory大(ApplicationContext的父接口)~ 這個類的主要功能就是将ApplicationContext之外的一些instance執行個體加入到Spring Application上下文中。如将JobInstance加入進來。

該類擷取方式:org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()

這就是為什麼我們可以直接在MyJobFacoty中使用該bean。

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/142326.html原文連結:https://javaforall.cn