Struts2 源码学习(一):模拟拦截器

来源:互联网 发布:mac怎么安装破解版ps 编辑:程序博客网 时间:2024/05/01 21:33

   这是一篇模拟Struts2拦截器的文章,模拟就不可能和Struts2的一样,但是我尽量需找模拟的重点,理解思路...好了不多说了,现在开始了

首先来看一下,Struts2 框架的整个流程图

Struts2 的流程图

这个图把Struts 2 的整个处理流程详细地描述出来,在这里我再讲一下

现在我们顺序来进行模拟

1、按照Struts 2,首先创建一个Action接口

Action.java

在Struts2中它提供了一个ActionSupport抽象类,这个除了实现Action接口以外,还实现了一系列的接口,比如说验证的接口,等于说这个ActinoSupport是一个工具类,所以在实际的开发中,我们就继承ActinSupport类就行

ActionSupport.java


 

这里写了其中的一个validate(),当验证的时候就会用到这个

最后实现自己的一个Action

MyAction.java

 

2、创建拦截器

首先,创建一个Interceptor接口

Interceptor.java

Struts2 中另外提供一个AbstractInterceptor类,该类提供了一个init和destory方法的空实现,如果我们实现的拦截器不需要打开资源,则可以无需实现两个方法。可见,用继承AbstractInterceptor类来实现自定义拦截器会更加简单

AbstractInterceptor.java

下面是自己实现的两个Interceptor

MyInterceptor_1.java

MyInterceptor_2.java

 

3、接下来写的我觉得是最重要的部分了,ActionInvocation接口,先来看看ActionInvocation的描述,这里就自己拿文档里面的解释来了

An ActionInvocation represents the execution state of an Action. It holds the Interceptors and the Action instance. By repeated re-entrant execution of the invoke() method, initially by the ActionProxy, then by the Interceptors, the Interceptors are all executed, and then the Action and the Result.

也就是说ActionInvocation是整个Aciton执行的控制者

现在来看看ActionInvocation接口

ActionInvocation.java

同样为ActionInvocation提供了实现类DefaultActionInvocation

DefaultActionInvocation.java

 

4、测试,这里是直接创建Action进行测试,说到这里这就体现了Struts 2的一个好处了,Struts 1 的一个主要的问题就是execute()方法依赖于Servlet API,这使得Aciton测试要依赖Web容器。为了脱离Web容器测试Struts 1的Action,必须借助第三方的扩展:Struts TestCase,该扩展下包含了系列的Mock对象(模拟了HttpServletRequest和HttpServletResponse对象),从而可以脱离容器测试Action,Struts 2 可以通过初始化、设置属性、调用方法来测试。

Test.java

 测试结果

 

5、总结

    这里我们没有模拟Struts 2 中很重要的一个东西ActionProxy,有机会的话以后模拟,好了我们再从代码的角度来讲一下Struts 2的处理流程:

   actionProxy.execute()--->invocation.invoke()---->interceptor.interceptor()--->action.execute()--->返回

在这里解释一下,当请求一个Action后,不是直接调用Action的execute方法,而是调用其代理ActionProxy的方法,ActionPrxoy中有ActionInvocation的引用,ActioinProxy代理的execute()方法被调用,execute方法中又调用ActionInvocation(由DefaultActionInvocation处理)的invoke()方法,invokef方法中有Interceptor的interceptor()方法,在这个时候通过

  resultCode = interceptor.getInterceptor().intercept(this);

循环执行interceptor,最后当没有Interceptor后,调用Action的execute方法,之后原路返回。

    这就是整个过程了,其中有不足,希望留言改正。

原创粉丝点击