struts组件,UI组件,标签,模板究竟是什么(1)

来源:互联网 发布:天刀网络不稳定怎么办 编辑:程序博客网 时间:2024/05/16 11:16


struts2在对xwork进行封装过程中主要做几个工作:全新分发器系统;拦截器扩展以及视图扩展.这三个方面是struts2所做的最主要工作,这三个工作尤其以视图扩展最为丰富,内容也是最多的,最复杂的,在网上经常听到UI组件,标签之类讨论,但它们究竟是什么我确实是一知半解,现在在工程中需要用到相关的视图技术,所以花点时间把研究下,顺便也记录一下心得体会

其实在struts2中视图技术以各种模板技术最为突出,其中的jsp视图也是以模板体系统结构进行管理,虽然它并不是一种模板技术. 以模板为中心衍生出很多比较容易混淆的概念,下面就对这些概念进行一下解释:

在struts2中有一个组件的概念,其实这个概念是从xwork工程引入的,从广义上讲所有被xwork内部容器进行管理的对象都可以称之为组件,但在struts2中谈组件的时候又多了层含义,这究竟是什么呢?它其实是对各种模板技术中使用标签,宏,指令等进行的一种深层次的抽象,这个些对象被放在componet包中,这些组件对象是可以为多种模板技术共享使用的对象,而在这些组件对象中也一类比较特别的子类组件它们往往与UI界面相关,尤其与前台的表单元素相关,它们被称之为UI  组件,实际也没有什么特别之处.其实它们的神奇之处主要在于它们是怎么与前台进行匹配的.此我先有jsp标签为例进行分析,再将分析过滤其它模板技术.

在分析jsp标签与组件对象的适配之前,快速把jsp标签过一扁,可以参考下面的jsp标签的类结构图,与执行流程图:

jspTag类结构图

jspTag类继承结构图

jspTag执行流程图

jspTag执行流程图

struts2的jsp标签实现也是采用的传统标签实现方式,而且流程控制使用的是最复杂的一种情况即BodyTag,在struts2中的实现标签的基类中有一个类被称为ComponentTagSupport,它是组件jsp标签支持类,这个类主要规范了struts2标签的一个主体结构,并将实际的标签服务委托给了 一个实际的component对象来完成,并为component对象抽象出了三个基本的回调方法,这三个方法分别为:{@link Component#start(java.io.Writer)},{@link Component#usesBody()} {@link Component#end(java.io.Writer, String)} 这三个方法实际是对BodyTagSupport 流程规范的一个简化.但其中的功能却一点没少,这可以看成是ComponentTag与Component之间的 桥梁,最终演化出两个继承体系ComponentTag继承与Component继承,这两类对象之间是协作关系, ComponentTag类型的类总是依赖一个相应的Component类型的类,这两种类型的类之间实际是有分工的,Component主要处理业务逻辑方面的问题,ComponentTag类型的类主要是负责与页面上的 参数进行接口,及流程规范. 
 另外此种分离的最重要的一个因素是为了组件共享,即共享component组件类,而ComponentTagSupport可以看成是jsp视图技术的一个应用,其实component组件类也可以使用 在其它视图组件的抽象中.下面分别是ComponentTag继承体系统图与Component继承体系图可以参下图:

StrutsBodyTagSupport继承关系

StrutsBodyTagSupport继承关系

component继承关系

component继承关系

ComponentTagSupport类的源代码如下:

public abstract class ComponentTagSupport extends StrutsBodyTagSupport {    protected Component component;    public abstract Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res);    /**     * 此方法分离出一个component#end()方法,并确保组件对象的释放     */    public int doEndTag() throws JspException {        component.end(pageContext.getOut(), getBody());        component = null;        return EVAL_PAGE;    }    public int doStartTag() throws JspException {        component = getBean(getStack(), (HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse());        Container container = Dispatcher.getInstance().getContainer();        //从这里可以看出,组件可以被注入xwork容器的中的对象        container.inject(component);                populateParams();                //此处分离出component#start方法        boolean evalBody = component.start(pageContext.getOut());        if (evalBody) {        //这里分离出component#usesBody方法            return component.usesBody() ? EVAL_BODY_BUFFERED : EVAL_BODY_INCLUDE;        } else {            return SKIP_BODY;        }    }    protected void populateParams() {    }    public Component getComponent() {        return component;    }}

你可从上面的源代码中清楚的看到TagSupport中将doStartTag与doEndTag委托给了组件对象去完成,并且转换成了组件的三个回调方法#start,#end,#usesBody而在TagSupport体系类中需要做的主要工作是填充参数与创建建组件对象.

这一篇先写到这个地方,剩下的下一篇接着分析

原创粉丝点击