《项目总结》专栏地址:http://blog.csdn.net/column/details/project-summary.html
上期:
接下来,我来备忘一下,Worker的实现以及Worker的管理
下面,我采用一种自顶向下的方式来讲,从页面才可控制开始。
先来看一下页面的布局,了解具体需要些什么?
<tr> <td>任务名称</td> <td>当前状态</td> <td>操作</td> <td>执行一次</td> <td>是否随容器一同启动</td> </tr> <tr> <td><font color='red'>XXXworker</font></td> <td> #if($!{xXXScheduler}==1) <span style="color:green">启动</span> #elseif($!{xXXScheduler}==0) <span style="color:red">停止</span> #end </td> <td> #if(${xXXScheduler}==1) <a href="$!homeModule.getTarget("/task/xTask.action").addQueryData("status","stop").addQueryData("jobTask","xXXScheduler")">停止</a> #elseif(${xXXScheduler}==0) <a href="$!homeModule.getTarget("/task/xTask.action").addQueryData("status","start").addQueryData("jobTask","xXXScheduler")">启动</a> #end </a></td> <td><a href="$!homeModule.getTarget("/task/xTask_once.action").addQueryData("quartzBeanId","xXXQuartz")">执行</a> </td> <td>否</td> </tr>
从这里我们可以看出,有这么几个变量需要我们了解。Status,只是判断是否是启动与停止的状态量,jobTask是具体要执行的workerScheduler了,quartzBeanId也是具体要执行的workerQuartz了。Scheduler和Quartz,当然了,这个就需要我们在spring的配置文件里进行配置,而具体的类,也马上为你呈现。
<bean id="xXXTaskService" class="com.project.service.impl.ProjectXxxServiceImpl"/> <!-- 获取XXX信息时间任务 --> <bean id="xXXQuartz" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="xXXTaskService"/> <property name="targetMethod" value="dealWorker"/> <property name="concurrent" value="false"/> </bean> <bean id="xXXTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="xXXQuartz"/> <property name="cronExpression" value="0/10 * * * * ?"/> <!-- <property name="cronExpression" value="0 8 0/2 * * ?"/> --> </bean> <bean id="xXXScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="xXXTrigger"/> </list> </property> <property name="autoStartup"> <value>false</value> </property> <property name="quartzProperties"> <props> <prop key="org.quartz.threadPool.threadCount">1</prop> </props> </property> </bean> <bean name="schedulerMap" class="java.util.HashMap"> <constructor-arg> <map> <!--XXX项目scheuler--> <entry key="xXXScheduler" value-ref="xXXScheduler"/> </map> </constructor-arg> </bean> <bean id="taskService" class="com.project.service.impl.TaskServiceImpl"/>
在这里顺便把这个jar的pom的maven依赖贴给大家吧。
<dependency> <groupId>org.opensymphony.quartz</groupId> <artifactId>quartz</artifactId> <version>1.6.1</version> </dependency>
上面这个就是Spring的配置文件,从上而下来给大家说说,需要的配置,具体需要执行Worker的类,我这里是Service提供的服务,供Worker使用。接下来需要配置SpringFramework框架的Quartz了,在Quartz的bean里需要制定目标类,即我们配置的Service和具体的执行方法。再接下来,就需要配置springframework的Trigger触发器,指定具体的job,以及什么时间触发执行。再接下来可以看到,就是Scheduler了。可以用autoStartup指定是否随容器自动启动哦。而schedulerMap这个给bean是TaskService里的属性,具体待会儿给大家展示一下类,具体看一下。
那下面,就给大家展示一下TaskService的实现。
public ActionResult singleScheduler(String schedulerName, String status) { return doExecute(SINGLE_SCHEDULER_TYPE, schedulerName, status); } public ActionResult isStarted() { return doExecute(IS_START_TYPE, "isStarted", ""); } private ActionResult doExecute(int type, String schedulerName, String status) { ActionResult result = new ActionResult(); if (schedulerMap == null || schedulerMap.size() <= 0) { return result; } Iterator<String> it = schedulerMap.keySet().iterator(); Scheduler scheduler = null; try { while (it.hasNext()) { String key = it.next(); if (type == START_ALL_TYPE) { // 启动所有的时间程序 scheduler = schedulerMap.get(key); scheduler.start(); result.addResult(key, "1"); } else if (type == STOP_ALL_TYPE) { // 关闭所有的时间程序 scheduler = schedulerMap.get(key); scheduler.standby(); result.addResult(key, "0"); } else if (type == SINGLE_SCHEDULER_TYPE) { // 启动一个指定的时间程序 if (key.equals(schedulerName)) { scheduler = schedulerMap.get(key); if (status.equals("start")) { scheduler.start(); } else if (status.equals("stop")) { scheduler.standby(); } } } else if (type == IS_START_TYPE) { scheduler = schedulerMap.get(key); if (scheduler.isStarted()) { result.addResult(key, "1"); if (scheduler.isInStandbyMode()) { result.addResult(key, "0"); } } else { result.addResult(key, "0"); } // setTimeTaskUseQueueSzie(key,result); } } result.setSuccess(true); result.setResultCode("system.timetask.execute.success"); logger.info("Method:" + schedulerName + "--->success"); } catch (SchedulerException e) { result.setSuccess(false); result.setResultCode("system.timetask.execute.error"); logger.error("Method:" + schedulerName + "--->error", e); } return result; } public ActionResult doOnceMethod(String quartzBeanId) { ActionResult result = new ActionResult(); /*拿到servletContext*/ ServletContext servletContext = ServletActionContext.getServletContext(); /*再find the web application context*/ WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); /*反射*/ MethodInvokingJobDetailFactoryBean b = ((MethodInvokingJobDetailFactoryBean) (((JobDetail) wac.getBean(quartzBeanId)).getJobDataMap().get("methodInvoker"))); Method method = b.getPreparedMethod(); try { method.invoke(b.getTargetObject(),null); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } result.setSuccess(true); return result; }
利用反射原理,来实现页面控制quartz的执行的。而在action层,就需要这几个参数而已。接下来把Action的方法贴出来看看。
public String execute() throws Exception { // if (!taskService.isVisitAuth()) { //LogHelper.dyManCommon.info("worker"+jobTask+":状态"+status); toVm(taskService.singleScheduler(jobTask, status)); toVm(taskService.isStarted()); //cleanCache(); return SUCCESS; // } else { // System.out.println("启动失败"); /// return "checkVisitAuth"; // } }
在Action就是做一下判断,接着向下调用而已,也挺简单的。
总结一下:
首先要有SpringQuartz,需要了解TA的配置,用Spring来管理Scheduler,所以要了解配置。
再次,从SchedulerMap中通过key拿到Scheduler来进行启动(scheduler.start())与关闭(scheduler.standby(););
最后,向页面输出操作的结果。
然而通过执行一次的那种,需要拿到ServletContext,再取到WebApplicationContext,再去得到MethodInvokingJobDetailFactoryBean,反射得到具体要执行的Worker。
------------------------------------------------------
A father's greatest dream is that his child's life is filled with joy.
父亲最大的梦想就是让孩子的生活充满快乐。
下期: