现在的位置: 首页 > 综合 > 正文

电影票项目之页面控制Worker

2018年04月10日 ⁄ 综合 ⁄ 共 5859字 ⁄ 字号 评论关闭

《项目总结》专栏地址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.

父亲最大的梦想就是让孩子的生活充满快乐。

下期:

 电影电子票项目-Worker多线程

抱歉!评论已关闭.