Here's a class and some paraphernalia I use to schedule a method call on a named bean.
Michael
Code:
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.support.ArgumentConvertingMethodInvoker;
import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;
import org.springframework.util.MethodInvoker;
/**
* Bean that uses a
* <a href="http://quartz.sourceforge.net/">Quartz</a>
* scheduler to invoke a method on a named bean in a
* <a href="http://www.springframework.org/">Spring</a>
* {@link org.springframework.context.ApplicationContext}.
*/
public class MethodInvocationSchedulerBean implements InitializingBean {
private static final String APPLICATION_CONTEXT_KEY = "applicationContext";
private static final String TARGET_BEAN_NAME_KEY = "target";
private static final String METHOD_NAME_KEY = "method";
private static final String ARGUMENTS_KEY = "arguments";
private Scheduler _scheduler;
private String _group;
public void setScheduler( Scheduler scheduler ) {
_scheduler = scheduler;
}
public void setGroup( String group ) {
_group = group;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(_scheduler, "scheduler property must be set");
Assert.hasText(_group, "group property must not be empty");
}
public void scheduleInvocation(
Date when,
String beanName,
String methodName,
Object[] args) throws SchedulerException {
Assert.notNull(when, "Date must not be null");
Assert.hasText(beanName, "beanName must not be blank");
Assert.hasText(methodName, "methodName must not be blank");
String name = beanName + '#' + methodName;
_scheduler.scheduleJob(
createJobDetail(beanName, methodName, args, name),
createTrigger(name, when));
}
private Trigger createTrigger( String name, Date when) {
return new SimpleTrigger(name, _group, when);
}
private JobDetail createJobDetail(
String beanName,
String methodName,
Object[] args,
String name) {
JobDetail detail = new JobDetail(
name, _group,
ScheduledInvocationJob.class,
true, false, false);
detail.getJobDataMap().put(TARGET_BEAN_NAME_KEY, beanName);
detail.getJobDataMap().put(METHOD_NAME_KEY, methodName);
detail.getJobDataMap().put(ARGUMENTS_KEY, args);
return detail;
}
public static class ScheduledInvocationJob implements Job {
public void execute( JobExecutionContext context )
throws JobExecutionException {
try {
ApplicationContext appCtx = getApplicationContext(context);
JobDataMap data = context.getJobDetail().getJobDataMap();
String beanName = data.getString(TARGET_BEAN_NAME_KEY);
Object target = appCtx.getBean(beanName);
String methodName = data.getString(METHOD_NAME_KEY);
Object[] args = (Object[])data.get(ARGUMENTS_KEY);
invokeMethod(target, methodName, args);
} catch (JobExecutionException e) {
throw e;
} catch (Exception e) {
throw new JobExecutionException(e);
}
}
private void invokeMethod(Object target, String methodName, Object[] args)
throws Exception {
MethodInvoker inv = new ArgumentConvertingMethodInvoker();
inv.setTargetObject(target);
inv.setTargetMethod(methodName);
inv.setArguments(args);
inv.prepare();
inv.invoke();
}
private ApplicationContext getApplicationContext( JobExecutionContext context )
throws Exception {
ApplicationContext appCtx = null;
appCtx = (ApplicationContext)context.getScheduler()
.getContext().get(APPLICATION_CONTEXT_KEY);
if (appCtx == null) {
throw new JobExecutionException(
"No application context available in scheduler context for key \"" + APPLICATION_CONTEXT_KEY + "\"");
}
return appCtx;
}
}
}
applicationContext.xml:
Code:
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>
<bean id="reloadscheduler"
class="app.MyReloadScheduler">
<constructor-arg index="0">
<bean class="de.schuerig.util.MethodInvocationSchedulerBean">
<property name="scheduler"><ref bean="scheduler"/></property>
<property name="group"><value>MyGroup</value></property>
</bean>
</constructor-arg>
</bean>
Bean that schedules a method invocation:
Code:
public class MyReloadScheduler implements ReloadScheduler {
private static final String TARGET_BEAN = "someBean";
private final MethodInvocationSchedulerBean _scheduler;
public MyReloadScheduler(MethodInvocationSchedulerBean scheduler) {
_scheduler = scheduler;
}
public void scheduleReload(
Date when )
throws SchedulerException {
_scheduler.scheduleInvocation(when, TARGET_BEAN, "reload", null);
}
...