注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

和申的个人主页

专注于java开发,1985wanggang

 
 
 

日志

 
 

WEBX2.0学习源码分析(四)初识 Pipeline  

2011-12-27 00:31:46|  分类: WebX |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
前面看见在webx中有调用pipeline的相关东西.
        try {
if (tryCatchFinally == null) {
pipeline.invoke(rundata);
} else {
tryCatchFinally.invokeTryPipeline(rundata);
}
} catch (PipelineException e) {
throw new WebxException(e);
}
 


/**
* 代表一组顺序执行的操作,好象液体流过一根管道一样。
*
* <p>
* Pipeline的概念是从Catalina项目(也就是tomcat)中借鉴而来的。通过pipeline,我们不需要将
* 代码的执行过程写死在程序中,只需要提供一个定制的XML文件,就可以知道如何完成整个过程。
* </p>
*
* @author Michael Zhou
* @version $Id: Pipeline.java 948 2004-04-27 03:59:02Z baobao $
*/
public interface Pipeline {
/**
* 初始化pipeline。
*
* @throws PipelineInitializationException 如果初始化失败
*/
void init() throws PipelineInitializationException;

/**
* 取得pipeline的唯一标识符。
*
* @return pipeline的唯一标识符
*/
String getId();

/**
* 取得创建此pipeline的<code>PipelineService</code>实例。
*
* @return 创建此pipeline的<code>PipelineService</code>实例
*/
PipelineService getPipelineService();

/**
* 取得当前pipeline的配置信息。
*
* @return 当前pipeline的配置信息
*/
Configuration getConfiguration();

/**
* 取得pipeline的长度。
*
* @return pipeline中包含的valve数量
*/
int getLength();

/**
* 取得指定index的<code>Valve</code>。
*
* @return 指定index处的<code>Valve</code>实例,如果未找到,则返回<code>null</code>
*/
Valve getValve(int index);

/**
* 跳转到指定名称的label。
*
* @param label 标签名
*
* @throws LabelNotFoundException 标签未找到
*/
void gotoLabel(PipelineContext pipelineContext, String label)
throws LabelNotFoundException;

/**
* 重新开始执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
void invoke(PipelineContext pipelineContext) throws PipelineException;

/**
* 开始执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
void invokeNext(PipelineContext pipelineContext) throws PipelineException;
}

如果没有tryCatchFinally,使用下面调用方式时候。
pipeline.invoke(rundata);
会调用DefaultPipeline的invoke方法,

/**
* <code>Pipeline</code>的默认实现。
*
* @author Michael Zhou
* @version $Id: DefaultPipeline.java 956 2004-04-27 06:18:10Z baobao $
*/
public class DefaultPipeline implements PipelineInternal {

。。。
/**
* 重新开始执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
public void invoke(PipelineContext pipelineContext) throws PipelineException {
// 清除step,重新开始。
setStep(pipelineContext, 0);

// 执行下一步。
invokeNext(pipelineContext);
}

}

然后调用invokeNext


/**
* 开始执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
public void invokeNext(PipelineContext pipelineContext)
throws PipelineException {
ValveForward forward = null;

for (int step = getStep(pipelineContext); step < getLength();
step = getStep(pipelineContext)) {
setStep(pipelineContext, step + 1);

Valve valve = getValve(step);

if (log.isDebugEnabled()) {
String label = valve.getLabel();

if (StringUtil.isEmpty(label)) {
log.debug("Entering valve[step=" + step + "]: "
+ getValve(step).getClass().getName());
} else {
log.debug("Entering valve[step=" + step + ", label=" + label + "]: "
+ getValve(step).getClass().getName());
}
}

try {
forward = valve.invoke(pipelineContext);
} finally {
if (log.isDebugEnabled()) {
String label = valve.getLabel();

if (StringUtil.isEmpty(label)) {
log.debug("..exited valve[step=" + step + "]: "
+ getValve(step).getClass().getName());
} else {
log.debug("..exited valve[step=" + step + ", label=" + label + "]: "
+ getValve(step).getClass().getName());
}
}
}

if (forward != null) {
break;
}
}

if (forward != null) {
log.debug("Forward to: " + forward);

try {
forward.invoke(this, pipelineContext);
} finally {
log.debug("Forward returned: " + forward);
}
}
}

看看其中的这句,看了不是所有的Valve都有forward的返回值,

  if (forward != null) {
break;
}
比如,这类的SubPipelineValve是没有返回值得,那显然,这个Valve的东西是,从开始到最终,是一趟管线,中间有一些没有出水口,只是转接,过滤的功能,最后有几个出水的阀门,可以直接将水流用来洗脸,烧水。作为最后渲染vm,jsp等来使用

/**
* 内嵌pipeline的valve。
*
* @author Michael Zhou
* @version $Id: SubPipelineValve.java 976 2004-04-30 02:05:31Z baobao $
*/
public class SubPipelineValve extends AbstractValve {

/**
* 处理请求。
*
* @param pipelineContext 运行时上下文
*
* @return 下一步行为的指令
*
* @throws PipelineException 如果处理失败
*/
public ValveForward invoke(PipelineContext pipelineContext)
throws PipelineException {
invokeSubPipeline(pipelineContext);

return null;
}

}


如果forward不为空,它还会发挥一些余热,去

if (forward != null) {
log.debug("Forward to: " + forward);

try {
forward.invoke(this, pipelineContext);
} finally {
log.debug("Forward returned: " + forward);
}
}

可以跳转到知道的label,看来可以使用label来实现跳转

/**
* 转到指定的label。
*
* @author Michael Zhou
* @version $Id: GotoLabel.java 948 2004-04-27 03:59:02Z baobao $
*/
public class GotoLabel implements ValveForward {
private String label;

/**
* 创建<code>GotoLabel</code>对象。
*
* @param label label名,不能为空
*/
public GotoLabel(String label) {
this.label = StringUtil.trimToNull(label);
}

/**
* 执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipeline 要执行的管道
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
public void invoke(Pipeline pipeline, PipelineContext pipelineContext)
throws PipelineException {
if (this.label == null) {
throw new PipelineException("Label should not be empty");
}

pipeline.gotoLabel(pipelineContext, label);
pipeline.invokeNext(pipelineContext);
}

/**
* 显示字符串。
*
* @return 字符串表示
*/
public String toString() {
return "GotoLabel: " + label;
}
}

另一种是中的执行。


/**
* 中断一个pipeline的指令。
*
* @author Michael Zhou
* @version $Id: BreakPipeline.java 968 2004-04-28 04:56:17Z baobao $
*/
public class BreakPipeline implements ValveForward {
/**
* 执行pipeline。Pipeline将按顺序执行pipeline中的所有<code>Valve</code>。
*
* <p>
* 多个线程将访问同一个<code>Pipeline</code>实例。因此<code>Pipeline</code>的实现必须确保多线程能独立处理自身的状态。
* </p>
*
* @param pipeline 要执行的管道
* @param pipelineContext 运行时状态
*
* @throws PipelineException 如果处理失败
*/
public void invoke(Pipeline pipeline, PipelineContext pipelineContext)
throws PipelineException {
}

/**
* 显示字符串。
*
* @return 字符串表示
*/
public String toString() {
return "BreakPipeline";
}
}

比如下面一个pipeline.xml文件

<?xml version="1.0" encoding="GB2312"?>

<pipeline>
<valve class="com.alibaba.service.pipeline.TryCatchFinallyValve">
<try>
<valve class="com.alibaba.turbine.pipeline.SetLoggingContextValve"/>
<valve class="com.alibaba.intl.commons.web.valve.SetLocaleValve" defaultLocale="en_US" defaultCharset="utf-8"/>
<valve class="com.alibaba.turbine.pipeline.AnalyzeURLValve"/>

<valve class="com.alibaba.intl.moree.core.webxlayout.valve.IntlBopsValve"/>
<!-- 检查页面的授权,如果当前用户无权访问该页面,则跳转到sign in页面 -->
<valve class="com.alibaba.intl.moree.core.webxlayout.valve.PrivilegeValve" label="processModule" goto="redirectTarget"/>
<valve class="com.alibaba.intl.riskbops.web.common.valve.RiskBopsEventTypeValve" goto="redirectTarget" />
<valve class="com.alibaba.turbine.pipeline.ChooseValve">
<when extension="jsp, vm">
<valve class="com.alibaba.intl.riskbops.web.common.valve.BopsWebUserInfoTransmitValve" />
<valve class="com.alibaba.turbine.pipeline.PerformActionValve" actionParam="action"/>
<valve class="com.alibaba.turbine.pipeline.PerformScreenTemplateValve"/>
<valve class="com.alibaba.intl.riskbops.web.common.valve.BopsWebUserInfoTransmitValve" action="clean" />

</when>
<when extension="do">
<valve class="com.alibaba.turbine.pipeline.PerformActionValve" actionParam="action"/>
<valve class="com.alibaba.turbine.pipeline.PerformScreenValve"/>
</when>
</valve>
<valve class="com.alibaba.turbine.pipeline.RedirectTargetValve" goto="processModule" label="redirectTarget"/>
<valve class="com.alibaba.intl.moree.core.webxlayout.valve.IntlBopsValve" action="commit"/>
</try>
<catch>
<valve target="error.vm" class="com.alibaba.turbine.pipeline.SetErrorPageValve"/>
<valve class="com.alibaba.turbine.pipeline.PerformScreenTemplateValve"/>
<valve class="com.alibaba.intl.moree.core.webxlayout.valve.IntlBopsValve" action="commit"/>
</catch>
<finally>
<valve class="com.alibaba.turbine.pipeline.SetLoggingContextValve" action="cleanup"/>
</finally>
</valve>
</pipeline>

看见了好几个goto,不知道这东西如果配错了是不是也会有死循环,哈哈
  评论这张
 
阅读(1257)| 评论(3)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016