我们系统中原有的基于spring3自带的task,并使用注解方式制定调度策略。单由于需求需要动态定制添加、修改、删除任务。spring自带的task无法满足需求。所以考虑使用spring+quartz。网上很多人说spring3+才能使用quartz2.+的版本,正好我们使用的spring版本为spring 3+,所以兴冲冲的使用了quartz-2.2.1的最新版本。通过搭建环境测试完美解决了动态定制任务的需求。参考(http://www.meiriyouke.net/?p=140),本文不详细叙述这种方式。只贴出源码
quartz对于集群方式采取数据库同步方式。以上方式使用spring 3+quartz2.2只能采用单机环境执行,所有调度都保存在内存中无法进行集群,所以考虑将dataSource注入到schedulerFactoryBean中,但是悲剧的是报“序列化”的错误。在网上找到解决方式是替换两个类,但是只有针对于quartz1版本的替换方式,针对于2版本的替换还没有~~~
无奈之使用了spring 3.1.3+quartz1.8 数据库方式搭建了动态定制任务。
1 spring3+quartz2.2
spring配置文件
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
任务运行入口,即Job实现类
public class QuartzJobFactory implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("任务成功运行"); ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob"); System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]"); } }
既然要动态的创建任务,我们的任务信息当然要保存在某个地方了,这里我们新建一个保存任务信息对应的实体类
package com.adtec.moia.rsp.engine; import java.io.Serializable; public class ScheduleJob implements Serializable{ /** 任务id */ private String jobId; /** 任务名称 */ private String jobName; /** 任务分组 */ private String jobGroup; /** 任务状态 0禁用 1启用 2删除*/ private String jobStatus; /** 任务运行时间表达式 */ private String cronExpression; /** 任务描述 */ private String desc; /**任务调用实现*/ private String classFullName; public String getJobId() { return jobId; } public void setJobId(String jobId) { this.jobId = jobId; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getJobStatus() { return jobStatus; } public void setJobStatus(String jobStatus) { this.jobStatus = jobStatus; } public String getCronExpression() { return cronExpression; } public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getClassFullName() { return classFullName; } public void setClassFullName(String classFullName) { this.classFullName = classFullName; } }
动态创建任务的驱动类
package com.adtec.moia.rsp.engine; import java.util.Date; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.DateBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.TriggerKey; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.stereotype.Service; import com.adtec.moia.base.exception.ServiceException; import com.adtec.moia.rsp.task.QuartzJobFactory; public class TaskEngineService { private SchedulerFactoryBean schedulerFactoryBean; public void addTask(ScheduleJob job1) throws ServiceException, Exception { Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); if(null==trigger){ Class<?> class1=Class.forName(job.getClassFullName()); Class<? extends Job> jobClass = (Class<? extends Job>) class1; JobBuilder jobBuilder= JobBuilder.newJob(jobClass); JobDetail jobDetail =jobBuilder.withIdentity(job.getJobName(),job.getJobGroup()).build(); jobDetail.getJobDataMap().put(job.getClassFullName(), job); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } JobDetail job = JobBuilder.newJob(QuartzJobFactory.class).withIdentity("job1", "group1").build(); Date runTime = DateBuilder.evenMinuteDate(new Date()); CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build(); scheduler.scheduleJob(job, trigger); scheduler.start(); } public void stopTask(ScheduleJob job) throws ServiceException, Exception { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup()); scheduler.pauseJob(jobKey); } public void resumeJob(ScheduleJob job) throws ServiceException, Exception { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup()); scheduler.resumeJob(jobKey); } public void removeTask(ScheduleJob job) throws ServiceException, Exception { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup()); scheduler.deleteJob(jobKey); } public void startNowTask(ScheduleJob job) throws SchedulerException{ Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup()); scheduler.triggerJob(jobKey); } public void refreshTask(ScheduleJob job) throws ServiceException, Exception { Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup()); //获取trigger,即在spring配置文件中定义的 bean id="myTrigger" CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build(); //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } //
执行测试主要代码:
//测试任务执行 ScheduleJob job=new ScheduleJob(); job.setJobId("10001"); job.setJobName("data_import"); job.setJobGroup("dataWork"); job.setJobStatus("1"); job.setCronExpression("0/5 * * * * ?"); job.setDesc("数据导入任务"); job.setClassFullName("com.adtec.moia.rsp.task.QuartzJobFactory"); try { Class.forName(job.getClassFullName()); taskEngineService.addTask(job); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
2 spring3+quartz1.8
需要jar包:
spring核心包+quartz需要包。我们项目中的包包括:
+
spring配置文件中注入:
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="configLocation" value="classpath:quartz.properties" /> <property name="dataSource" ref="dataSource" /> <property name="triggers"> <list> </list> </property> </bean>
其中dataSource是quartz连接数据库的信息,quartz.properties为quartz配置信息。具体如下:标红部分表示使用数据库方式(为了集群)
#============================================================================ # Configure Main Scheduler Properties #============================================================================ org.quartz.scheduler.instanceName = RspDefaultQuartzScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export = false org.quartz.scheduler.rmi.proxy = false org.quartz.scheduler.wrapJobExecutionInUserTransaction = false #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.misfireThreshold = 60000 org.quartz.jobStore.useProperties = false org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.txIsolationLevelSerializable = true org.quartz.jobStore.isClustered = true org.quartz.jobStore.clusterCheckinInterval = 15000 org.quartz.jobStore.dontSetAutoCommitFalse = true
重写MethodInvokingJobDetailFactoryBean类,避免序列化错误
public class MethodInvokingJobDetailFactoryBean implements FactoryBean, BeanNameAware, InitializingBean { private Log logger = LogFactory.getLog(getClass()); /** * The JobDetail produced by the <code>afterPropertiesSet</code> method of this Class will be assigned to the Group specified by this property. Default: Scheduler.DEFAULT_GROUP * @see #afterPropertiesSet() * @see Scheduler#DEFAULT_GROUP */ private String group = Scheduler.DEFAULT_GROUP; /** * Indicates whether or not the Bean Method should be invoked by more than one Scheduler at the specified time (like when deployed to a cluster, and/or when there are multiple Spring ApplicationContexts in a single JVM<i> - Tomcat 5.5 creates 2 or more instances of the DispatcherServlet (a pool), which in turn creates a separate Spring ApplicationContext for each instance of the servlet</i>) * <p> * Used by <code>afterPropertiesSet</code> to set the JobDetail.jobClass to MethodInvokingJob.class or StatefulMethodInvokingJob.class when true or false, respectively. Default: true * @see #afterPropertiesSet() */ private boolean concurrent = true; /** Used to set the JobDetail.durable property. Default: false * <p>Durability - if a job is non-durable, it is automatically deleted from the scheduler once there are no longer any active triggers associated with it. * @see <a href="http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html">http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html</a> * @see #afterPropertiesSet() */ private boolean durable = false; /** * Used by <code>afterPropertiesSet</code> to set the JobDetail.volatile property. Default: false * <p>Volatility - if a job is volatile, it is not persisted between re-starts of the Quartz scheduler. * <p>I set the default to false to be the same as the default for a Quartz Trigger. An exception is thrown * when the Trigger is non-volatile and the Job is volatile. If you want volatility, then you must set this property, and the Trigger‘s volatility property, to true. * @see <a href="http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html">http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html</a> * @see #afterPropertiesSet() */ private boolean volatility = false; /** * Used by <code>afterPropertiesSet</code> to set the JobDetail.requestsRecovery property. Default: false<BR> * <p>RequestsRecovery - if a job "requests recovery", and it is executing during the time of a ‘hard shutdown‘ of the scheduler (i.e. the process it is running within crashes, or the machine is shut off), then it is re-executed when the scheduler is started again. In this case, the JobExecutionContext.isRecovering() method will return true. * @see <a href="http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html">http://www.opensymphony.com/quartz/wikidocs/TutorialLesson3.html</a> * @see #afterPropertiesSet() */ private boolean shouldRecover = false; /** * A list of names of JobListeners to associate with the JobDetail object created by this FactoryBean. * * @see #afterPropertiesSet() **/ private String[] jobListenerNames; /** The name assigned to this bean in the Spring ApplicationContext. * Used by <code>afterPropertiesSet</code> to set the JobDetail.name property. * @see afterPropertiesSet() * @see JobDetail#setName(String) **/ private String beanName; /** * The JobDetail produced by the <code>afterPropertiesSet</code> method, and returned by the <code>getObject</code> method of the Spring FactoryBean interface. * @see #afterPropertiesSet() * @see #getObject() * @see FactoryBean **/ private JobDetail jobDetail; /** * The name of the Class to invoke. **/ private String targetClass; /** * The Object to invoke. * <p> * {@link #targetClass} or targetObject must be set, but not both. * <p> * This object must be Serializable when {@link #concurrent} is set to false. */ private Object targetObject; /** * The instance method to invoke on the Class or Object identified by the targetClass or targetObject property, respectfully. * <p> * targetMethod or {@link #staticMethod} should be set, but not both. **/ private String targetMethod; /** * The static method to invoke on the Class or Object identified by the targetClass or targetObject property, respectfully. * <p> * {@link #targetMethod} or staticMethod should be set, but not both. */ private String staticMethod; /** * Method arguments provided to the {@link #targetMethod} or {@link #staticMethod} specified. * <p> * All arguments must be Serializable when {@link #concurrent} is set to false. * <p> * I strongly urge you not to provide arguments until Quartz 1.6.1 has been released if you are using a JDBCJobStore with * Microsoft SQL Server. There is a bug in version 1.6.0 that prevents Quartz from Serializing the Objects in the JobDataMap * to the database. The workaround is to set the property "org.opensymphony.quaryz.useProperties = true" in your quartz.properties file, * which tells Quartz not to serialize Objects in the JobDataMap, but to instead expect all String compliant values. */ private Object[] arguments; /** * Get the targetClass property. * @see #targetClass * @return targetClass */ public String getTargetClass() { return targetClass; } /** * Set the targetClass property. * @see #targetClass */ public void setTargetClass(String targetClass) { this.targetClass = targetClass; } /** * Get the targetMethod property. * @see #targetMethod * @return targetMethod */ public String getTargetMethod() { return targetMethod; } /** * Set the targetMethod property. * @see #targetMethod */ public void setTargetMethod(String targetMethod) { this.targetMethod = targetMethod; } /** * @return jobDetail - The JobDetail that is created by the afterPropertiesSet method of this FactoryBean * @see #jobDetail * @see #afterPropertiesSet() * @see FactoryBean#getObject() */ public Object getObject() throws Exception { return jobDetail; } /** * @return JobDetail.class * @see FactoryBean#getObjectType() */ public Class getObjectType() { return JobDetail.class; } /** * @return true * @see FactoryBean#isSingleton() */ public boolean isSingleton() { return true; } /** * Set the beanName property. * @see #beanName * @see BeanNameAware#setBeanName(String) */ public void setBeanName(String beanName) { this.beanName = beanName; } /** * Invoked by the Spring container after all properties have been set. * <p> * Sets the <code>jobDetail</code> property to a new instance of JobDetail * <ul> * <li>jobDetail.name is set to <code>beanName</code><br> * <li>jobDetail.group is set to <code>group</code><br> * <li>jobDetail.jobClass is set to MethodInvokingJob.class or StatefulMethodInvokingJob.class depending on whether the <code>concurrent</code> property is set to true or false, respectively.<br> * <li>jobDetail.durability is set to <code>durable</code> * <li>jobDetail.volatility is set to <code>volatility</code> * <li>jobDetail.requestsRecovery is set to <code>shouldRecover</code> * <li>jobDetail.jobDataMap["targetClass"] is set to <code>targetClass</code> * <li>jobDetail.jobDataMap["targetMethod"] is set to <code>targetMethod</code> * <li>Each JobListener name in <code>jobListenerNames</code> is added to the <code>jobDetail</code> object. * </ul> * <p> * Logging occurs at the DEBUG and INFO levels; 4 lines at the DEBUG level, and 1 line at the INFO level. * <ul> * <li>DEBUG: start * <li>DEBUG: Creating JobDetail <code>{beanName}</code> * <li>DEBUG: Registering JobListener names with JobDetail object <code>{beanName}</code> * <li>INFO: Created JobDetail: <code>{jobDetail}</code>; targetClass: <code>{targetClass}</code>; targetMethod: <code>{targetMethod}</code>; * <li>DEBUG: end * </ul> * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see JobDetail * @see #jobDetail * @see #beanName * @see #group * @see MethodInvokingJob * @see StatefulMethodInvokingJob * @see #durable * @see #volatility * @see #shouldRecover * @see #targetClass * @see #targetMethod * @see #jobListenerNames */ 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 ? MethodInvokingJob.class : StatefulMethodInvokingJob.class); jobDetail.setDurability(durable); jobDetail.setVolatility(volatility); jobDetail.setRequestsRecovery(shouldRecover); if(targetClass!=null) jobDetail.getJobDataMap().put("targetClass", targetClass); if(targetObject!=null) jobDetail.getJobDataMap().put("targetObject", targetObject); if(targetMethod!=null) jobDetail.getJobDataMap().put("targetMethod", targetMethod); if(staticMethod!=null) jobDetail.getJobDataMap().put("staticMethod", staticMethod); if(arguments!=null) 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+"; targetClass: "+targetClass+"; targetObject: "+targetObject+"; targetMethod: "+targetMethod+"; staticMethod: "+staticMethod+"; arguments: "+arguments+";"); } finally { logger.debug("end"); } } /** * Setter for the concurrent property. * * @param concurrent * @see #concurrent */ public void setConcurrent(boolean concurrent) { this.concurrent = concurrent; } /** * setter for the durable property. * * @param durable * * @see #durable */ public void setDurable(boolean durable) { this.durable = durable; } /** * setter for the group property. * * @param group * * @see #group */ public void setGroup(String group) { this.group = group; } /** * setter for the {@link #jobListenerNames} property. * * @param jobListenerNames * @see #jobListenerNames */ public void setJobListenerNames(String[] jobListenerNames) { this.jobListenerNames = jobListenerNames; } /** * setter for the {@link #shouldRecover} property. * * @param shouldRecover * @see #shouldRecover */ public void setShouldRecover(boolean shouldRecover) { this.shouldRecover = shouldRecover; } /** * setter for the {@link #volatility} property. * * @param volatility * @see #volatility */ public void setVolatility(boolean volatility) { this.volatility = volatility; } /** * This is a cluster safe Job designed to invoke a method on any bean defined within the same Spring * ApplicationContext. * <p> * The only entries this Job expects in the JobDataMap are "targetClass" and "targetMethod".<br> * - It uses the value of the <code>targetClass</code> entry to get the desired bean from the Spring ApplicationContext.<br> * - It uses the value of the <code>targetMethod</code> entry to determine which method of the Bean (identified by targetClass) to invoke. * <p> * It uses the static ApplicationContext in the MethodInvokingJobDetailFactoryBean, * which is ApplicationContextAware, to get the Bean with which to invoke the method. * <p> * All Exceptions thrown from the execute method are caught and wrapped in a JobExecutionException. * * @see MethodInvokingJobDetailFactoryBean#applicationContext * @see #execute(JobExecutionContext) * * @author Stephen M. Wick */ public static class MethodInvokingJob implements Job { protected Log logger = LogFactory.getLog(getClass()); /** * When invoked by a Quartz scheduler, <code>execute</code> invokes a method on a Class or Object in the JobExecutionContext provided. * <p> * <b>Implementation</b><br> * The Class is identified by the "targetClass" entry in the JobDataMap of the JobExecutionContext provided. If targetClass is specified, then targetMethod must be a static method.<br> * The Object is identified by the ‘targetObject" entry in the JobDataMap of the JobExecutionContext provided. If targetObject is provided, then targetClass will be overwritten. This Object must be Serializable when <code>concurrent</code> is set to false.<br> * The method is identified by the "targetMethod" entry in the JobDataMap of the JobExecutionContext provided.<br> * The "staticMethod" entry in the JobDataMap of the JobExecutionContext can be used to specify a Class and Method in one entry (ie: "example.ExampleClass.someStaticMethod")<br> * The method arguments (an array of Objects) are identified by the "arguments" entry in the JobDataMap of the JobExecutionContext. All arguments must be Serializable when <code>concurrent</code> is set to false. * <p> * Logging is provided at the DEBUG and INFO levels; 8 lines at the DEBUG level, and 1 line at the INFO level. * @see Job#execute(JobExecutionContext) */ public void execute(JobExecutionContext context) throws JobExecutionException { try { logger.debug("start"); String targetClass = context.getMergedJobDataMap().getString("targetClass"); logger.debug("targetClass is "+targetClass); Class targetClassClass = null; if(targetClass!=null) { targetClassClass = Class.forName(targetClass); // Could throw ClassNotFoundException } Object targetObject = context.getMergedJobDataMap().get("targetObject"); logger.debug("targetObject is "+targetObject); String targetMethod = context.getMergedJobDataMap().getString("targetMethod"); logger.debug("targetMethod is "+targetMethod); String staticMethod = context.getMergedJobDataMap().getString("staticMethod"); logger.debug("staticMethod is "+staticMethod); Object[] arguments = (Object[])context.getMergedJobDataMap().get("arguments"); logger.debug("arguments are "+arguments); logger.debug("creating MethodInvoker"); MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetClass(targetClassClass); methodInvoker.setTargetObject(targetObject); methodInvoker.setTargetMethod(targetMethod); methodInvoker.setStaticMethod(staticMethod); methodInvoker.setArguments(arguments); methodInvoker.prepare(); logger.info("Invoking: "+methodInvoker.getPreparedMethod().toGenericString()); methodInvoker.invoke(); } catch(Exception e) { throw new JobExecutionException(e); } finally { logger.debug("end"); } } } public static class StatefulMethodInvokingJob extends MethodInvokingJob implements StatefulJob { // No additional functionality; just needs to implement StatefulJob. } public Object[] getArguments() { return arguments; } public void setArguments(Object[] arguments) { this.arguments = arguments; } public String getStaticMethod() { return staticMethod; } public void setStaticMethod(String staticMethod) { this.staticMethod = staticMethod; } public void setTargetObject(Object targetObject) { this.targetObject = targetObject; } }
具体任务
public class RspRunUserRightJob implements Serializable,Job { public void execute(JobExecutionContext jobexecutioncontext) throws JobExecutionException { System.out.println(":Job 执行~开始~"); System.out.println(); } }
任务管理公共类
/** * 功能/模块 :任务管理公共类 */ @Service("taskEngineService") public class TaskEngineService { @Resource(name = "schedulerFactoryBean") private StdScheduler schedulerFactoryBean; public void standbyTask(String triggerName, String execClass) throws ServiceException { try { schedulerFactoryBean.pauseTrigger(triggerName, Scheduler.DEFAULT_GROUP); schedulerFactoryBean.pauseJob(execClass, Scheduler.DEFAULT_GROUP); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } public void stopTask(String triggerName, String execClass) throws ServiceException { try { schedulerFactoryBean.pauseTrigger(triggerName, Scheduler.DEFAULT_GROUP); schedulerFactoryBean.deleteJob(execClass, Scheduler.DEFAULT_GROUP); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } public void startTask(JobDetail jobDetail, CronTriggerBean cronTriggerBean) throws ServiceException { try { schedulerFactoryBean.scheduleJob(jobDetail, cronTriggerBean); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } public void startTask(JobDetail jobDetail, SimpleTriggerBean simpleTriggerBean) throws ServiceException { try { schedulerFactoryBean.scheduleJob(jobDetail, simpleTriggerBean); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } public void startTask(SysTaskInfo sysTaskInfo) throws ServiceException { MethodInvokingJobDetailFactoryBean test = new MethodInvokingJobDetailFactoryBean(); if (SYS_TASK_INFO.TASK_STATUS_STOP.equals(sysTaskInfo.getTaskStatus())) { JobDetail jobDetail = null; try { jobDetail = new JobDetail(); jobDetail.setName(sysTaskInfo.getTaskId()); jobDetail.setGroup(sysTaskInfo.getTaskId()); jobDetail.setJobClass(Class.forName("com.adtec.moia.rsp.job.RspRunUserRightJob")); jobDetail.setDurability(false); jobDetail.setVolatility(false); jobDetail.setRequestsRecovery(false); jobDetail.getJobDataMap().put("targetClass", Class.forName("com.adtec.moia.rsp.job.RspRunUserRightJob")); jobDetail.getJobDataMap().put("targetMethod", "execute"); } catch (Exception e) { throw new ServiceException(e.getMessage()); } SysTriggerInfo sysTriggerInfo = sysTaskInfo.getSysTriggerInfo(); scheduJob(sysTaskInfo.getStartTime(), sysTaskInfo.getEndTime(), jobDetail, sysTriggerInfo, Scheduler.DEFAULT_GROUP); } else if ( SYS_TASK_INFO.TASK_STATUS_STANDBY.equals(sysTaskInfo.getTaskStatus())) { try { schedulerFactoryBean.resumeTrigger(sysTaskInfo.getTriggerId(), Scheduler.DEFAULT_GROUP); schedulerFactoryBean.resumeJob(sysTaskInfo.getExecClass(), Scheduler.DEFAULT_GROUP); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } } private void scheduJob(Date startTime, Date endTime, JobDetail jobDetail, SysTriggerInfo sysTriggerInfo, String group) throws ServiceException { try { if (SYS_TRIGGER_INFO.TRIGGER_TYPE_CRON.equals(sysTriggerInfo.getTriggerType())) { CronTriggerBean cronTriggerBean = new CronTriggerBean(); if (startTime != null) { cronTriggerBean.setStartTime(startTime); } if (endTime != null) { cronTriggerBean.setEndTime(endTime); } cronTriggerBean.setCronExpression(sysTriggerInfo .getCronExpression()); cronTriggerBean.setBeanName(sysTriggerInfo.getTriggerId()); cronTriggerBean.setJobDetail(jobDetail); cronTriggerBean.setGroup(group); cronTriggerBean.afterPropertiesSet(); schedulerFactoryBean.scheduleJob(jobDetail, cronTriggerBean); } else { SimpleTriggerBean simpleTriggerBean = new SimpleTriggerBean(); simpleTriggerBean.setBeanName(sysTriggerInfo.getTriggerId()); if (startTime != null) { simpleTriggerBean.setStartTime(startTime); } if (endTime != null) { simpleTriggerBean.setEndTime(endTime); } simpleTriggerBean.setRepeatCount(sysTriggerInfo .getRepeatCount()); simpleTriggerBean.setStartDelay(sysTriggerInfo.getStartDelay()); simpleTriggerBean.setRepeatInterval(sysTriggerInfo .getRepeatInterval()); simpleTriggerBean.setBeanName(sysTriggerInfo.getTriggerId()); simpleTriggerBean.setJobDetail(jobDetail); simpleTriggerBean.setGroup(group); simpleTriggerBean.afterPropertiesSet(); schedulerFactoryBean.scheduleJob(jobDetail, simpleTriggerBean); } } catch (ParseException e) { throw new ServiceException(e.getMessage()); } catch (SchedulerException e) { throw new ServiceException(e.getMessage()); } catch (Exception e) { e.printStackTrace(); } } }