了解了Quartz基本原理后,再回头看公司的程序:
BeanInvokingJobDetailFactoryBean 作为自定义的实现,里面有函数 afterPropertiesSet 调用了
jobdetail, 而jobdetail 会使用内部类BeanInvokingJob, BeanInvokingJob刚是用了反射进行调用各个job
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.StatefulJob;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.MethodInvoker;
public class BeanInvokingJobDetailFactoryBean implements
FactoryBean, BeanNameAware, InitializingBean, ApplicationContextAware
{
protected static ApplicationContext applicationContext;
private Log logger = LogFactory.getLog(getClass());
private String group = Scheduler.DEFAULT_GROUP;
private boolean concurrent = true;
private boolean durable = false;
private boolean volatility = false;
private boolean shouldRecover = false;
private String[] jobListenerNames;
private String beanName;
private JobDetail jobDetail;
private String targetBean;
private String targetMethod;
private Object[] arguments;
// targetBean getter setter 省略
// targetMethod getter setter 省略
public Object getObject() throws Exception
{
return jobDetail;
}
public Class getObjectType()
{
return JobDetail.class;
}
public boolean isSingleton()
{
return true;
}
public void setBeanName(String beanName)
{
this.beanName = beanName;
}
public void afterPropertiesSet() throws Exception
{
try
{
logger.debug("start");
logger.debug("Creating JobDetail "+beanName);
jobDetail = new JobDetail();
jobDetail.setName(beanName);
jobDetail.setGroup(group);
jobDetail.setJobClass(concurrent ? BeanInvokingJob.class :
StatefulBeanInvokingJob.class);
jobDetail.setDurability(durable);
jobDetail.setVolatility(volatility);
jobDetail.setRequestsRecovery(shouldRecover);
jobDetail.getJobDataMap().put("targetBean", targetBean);
jobDetail.getJobDataMap().put("targetMethod", targetMethod);
jobDetail.getJobDataMap().put("arguments", arguments);
logger.debug("Registering JobListener names with JobDetail object "+beanName);
if (this.jobListenerNames != null) {
for (int i = 0; i < this.jobListenerNames.length; i++) {
this.jobDetail.addJobListener(this.jobListenerNames[i]);
}
}
logger.info("Created JobDetail: "+jobDetail+"; targetBean: "+
targetBean+"; targetMethod: "+targetMethod+"; arguments: "+arguments+";");
}
finally
{
logger.debug("end");
}
}
public void setConcurrent(boolean concurrent)
{
this.concurrent = concurrent;
}
public void setDurable(boolean durable)
{
this.durable = durable;
}
public void setGroup(String group)
{
this.group = group;
}
public void setJobListenerNames(String[] jobListenerNames)
{
this.jobListenerNames = jobListenerNames;
}
public void setShouldRecover(boolean shouldRecover)
{
this.shouldRecover = shouldRecover;
}
public void setVolatility(boolean volatility)
{
this.volatility = volatility;
}
public void setApplicationContext(ApplicationContext context) throws BeansException
{
applicationContext = context;
}
public void setArguments(Object[] arguments)
{
this.arguments = arguments;
}
public static class BeanInvokingJob implements Job
{
protected Log logger = LogFactory.getLog(getClass());
public void execute(JobExecutionContext context) throws JobExecutionException
{
try
{
logger.debug("start");
String targetBean = context.getMergedJobDataMap().getString("targetBean");
logger.debug("targetBean is "+targetBean);
if(targetBean==null)
throw new JobExecutionException("targetBean cannot be null.", false);
String targetMethod = context.getMergedJobDataMap().getString("targetMethod");
logger.debug("targetMethod is "+targetMethod);
if(targetMethod==null)
throw new JobExecutionException("targetMethod cannot be null.", false);
Object argumentsObject = context.getMergedJobDataMap().get("arguments");
Object[] arguments = (argumentsObject instanceof String) ? null :
(Object[])argumentsObject;
logger.debug("arguments array is "+arguments);
Object bean = applicationContext.getBean(targetBean);
logger.debug("applicationContext resolved bean name/id '"+targetBean+"' to "+bean);
MethodInvoker beanMethod = new MethodInvoker();
beanMethod.setTargetObject(bean);
beanMethod.setTargetMethod(targetMethod);
beanMethod.setArguments(arguments);
beanMethod.prepare();
logger.info("Invoking Bean: "+targetBean+"; Method: "+
targetMethod+"; arguments: "+arguments+";");
beanMethod.invoke();
}
catch(JobExecutionException e)
{
throw e;
}
catch(Exception e)
{
throw new JobExecutionException(e);
}
finally
{
logger.debug("end");
}
}
}
public static class StatefulBeanInvokingJob extends BeanInvokingJob implements StatefulJob
{
// No additional functionality; just needs to implement StatefulJob.
}
}