1 16 17 package org.springframework.scheduling.quartz; 18 19 import java.lang.reflect.Constructor ; 20 import java.lang.reflect.InvocationTargetException ; 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 import org.quartz.JobDetail; 25 import org.quartz.JobExecutionContext; 26 import org.quartz.JobExecutionException; 27 import org.quartz.Scheduler; 28 import org.quartz.StatefulJob; 29 30 import org.springframework.beans.BeanUtils; 31 import org.springframework.beans.factory.BeanClassLoaderAware; 32 import org.springframework.beans.factory.BeanNameAware; 33 import org.springframework.beans.factory.FactoryBean; 34 import org.springframework.beans.factory.InitializingBean; 35 import org.springframework.beans.support.ArgumentConvertingMethodInvoker; 36 import org.springframework.util.ClassUtils; 37 import org.springframework.util.MethodInvoker; 38 39 65 public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethodInvoker 66 implements FactoryBean, BeanNameAware, BeanClassLoaderAware, InitializingBean { 67 68 73 private static final Constructor oldJobExecutionExceptionConstructor = 74 ClassUtils.getConstructorIfAvailable(JobExecutionException.class, 75 new Class [] {String .class, Exception .class, boolean.class}); 76 77 78 private String name; 79 80 private String group = Scheduler.DEFAULT_GROUP; 81 82 private boolean concurrent = true; 83 84 private String [] jobListenerNames; 85 86 private String beanName; 87 88 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 89 90 private JobDetail jobDetail; 91 92 93 98 public void setName(String name) { 99 this.name = name; 100 } 101 102 108 public void setGroup(String group) { 109 this.group = group; 110 } 111 112 122 public void setConcurrent(boolean concurrent) { 123 this.concurrent = concurrent; 124 } 125 126 134 public void setJobListenerNames(String [] names) { 135 this.jobListenerNames = names; 136 } 137 138 public void setBeanName(String beanName) { 139 this.beanName = beanName; 140 } 141 142 public void setBeanClassLoader(ClassLoader classLoader) { 143 this.beanClassLoader = classLoader; 144 } 145 146 protected Class resolveClassName(String className) throws ClassNotFoundException { 147 return ClassUtils.forName(className, this.beanClassLoader); 148 } 149 150 151 public void afterPropertiesSet() throws ClassNotFoundException , NoSuchMethodException { 152 prepare(); 153 154 String name = (this.name != null ? this.name : this.beanName); 156 157 Class jobClass = (this.concurrent ? (Class ) MethodInvokingJob.class : StatefulMethodInvokingJob.class); 159 160 this.jobDetail = new JobDetail(name, this.group, jobClass); 162 this.jobDetail.getJobDataMap().put("methodInvoker", this); 163 this.jobDetail.setVolatility(true); 164 this.jobDetail.setDurability(true); 165 166 if (this.jobListenerNames != null) { 168 for (int i = 0; i < this.jobListenerNames.length; i++) { 169 this.jobDetail.addJobListener(this.jobListenerNames[i]); 170 } 171 } 172 173 postProcessJobDetail(this.jobDetail); 174 } 175 176 181 protected void postProcessJobDetail(JobDetail jobDetail) { 182 } 183 184 185 public Object getObject() { 186 return this.jobDetail; 187 } 188 189 public Class getObjectType() { 190 return JobDetail.class; 191 } 192 193 public boolean isSingleton() { 194 return true; 195 } 196 197 198 202 public static class MethodInvokingJob extends QuartzJobBean { 203 204 protected static final Log logger = LogFactory.getLog(MethodInvokingJob.class); 205 206 private MethodInvoker methodInvoker; 207 208 private String errorMessage; 209 210 213 public void setMethodInvoker(MethodInvoker methodInvoker) { 214 this.methodInvoker = methodInvoker; 215 this.errorMessage = "Could not invoke method '" + this.methodInvoker.getTargetMethod() + 216 "' on target object [" + this.methodInvoker.getTargetObject() + "]"; 217 } 218 219 222 protected void executeInternal(JobExecutionContext context) throws JobExecutionException { 223 try { 224 this.methodInvoker.invoke(); 225 } 226 catch (InvocationTargetException ex) { 227 logger.warn(this.errorMessage, ex.getTargetException()); 228 if (ex.getTargetException() instanceof JobExecutionException) { 229 throw (JobExecutionException) ex.getTargetException(); 230 } 231 if (oldJobExecutionExceptionConstructor != null) { 232 Exception jobEx = (ex.getTargetException() instanceof Exception ) ? 233 (Exception ) ex.getTargetException() : ex; 234 throw (JobExecutionException) BeanUtils.instantiateClass( 235 oldJobExecutionExceptionConstructor, new Object [] {this.errorMessage, jobEx, Boolean.FALSE}); 236 } 237 else { 238 throw new JobExecutionException(this.errorMessage, ex.getTargetException()); 239 } 240 } 241 catch (Exception ex) { 242 logger.warn(this.errorMessage, ex); 243 if (oldJobExecutionExceptionConstructor != null) { 244 throw (JobExecutionException) BeanUtils.instantiateClass( 245 oldJobExecutionExceptionConstructor, new Object [] {this.errorMessage, ex, Boolean.FALSE}); 246 } 247 else { 248 throw new JobExecutionException(this.errorMessage, ex); 249 } 250 } 251 } 252 } 253 254 255 260 public static class StatefulMethodInvokingJob extends MethodInvokingJob implements StatefulJob { 261 262 } 265 266 } 267 | Popular Tags |