理解掌握Struts2Intercept的调用过程

本文主要用于理解掌握Struts2 Intercept的调用过程 及动态代理

前言:Struts2的 拦截器机制实际上是java设计模式中最重要的设计模式------动态代理  , 
 它的需求来源如下:
   一个class 有具体的 operation(method)  ,现在有一个需求是: 要在调用这个方法调用加上 一些业务(比如打印"Today is saturday     ") 在调用方法加入一些业务逻辑(比如  Tomorrow is sunday ,so we can play)
好,瞬间的思考可以得到如下实现方法

class proxy{
   
    public  static void myMetod(){
	 System.out.println("Today is saturday ");//新加业务逻辑 (前)
 System.out.println("we can't play any more"); //原来的业务需要打印的是we can't play any more
 System.out.println("  Tomorrow is sunday ,so we can play ");//新加业务逻辑 (后)
}

}


这样虽然也实现了我们想要的效果,但是,这样的代码是高度耦合的,完全不具备重用性,试想下,如果需求变了,现在要在100个方法上加入100个不同的前后调用,这样的代码修改量将会是 100的平方的2倍 ,能不能有一种高效的方法,你给我业务逻辑,我就可以完全重用的实现业务逻辑
 AOP 编程, (aspect to programing ) 为此而生。 
想要达到的效果如下



class DynamicProxy{  
  
     public static void main(String[] arg){
		  	
	DynamiPproxy  dynamicproxy  =new  
DynamiPproxy(proxy.myMethod(),
beforeMethod(),
AfterMethod());  //第一个参数是原来方法,第二个参数是业务调用前执行方法,第三个参数是业务调用钩执行方法
        
			dynamicproxy.invoke();  //调用
// 这里dynamicproxy就是 原来proxy的一个动态代理,它会根据后面的三个参数生成一个类, 里面有 一个方法, 和上面proxy类中的myMethod方法体一样,然后执行 invoke 方法!
//庆幸的是这一切都有人已经帮我们写好,并出书育人:java设计模式
//     这样我们就可以只修改 参数的具体实现 ,就可以非常解耦的实现我们的AOP需求
 
	}     
      public void beforeMethod(){
 System.out.println("Today is saturday ");//新加业务逻辑 (前)

}


   public void before AfterMethod(){
 System.out.println("  Tomorrow is sunday ,so we can play ");//新加业务逻辑 (后)

}


}

 具体的动态代理实现可以看其他博客
http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html
http://blog.csdn.net/heyutao007/article/details/49738887



我们再来看Struts2的拦截器



以下是例子

Struts.xml拦截器定义如下

    <package name="interceptor" extends="struts-default">
        <!-- 定义多个拦截器 -->
        <interceptors>
            <!-- 定义一个拦截器 -->
    <interceptor name="my1" class="com.baizhi.action2.MyInterceptor"></interceptor>
<interceptor name="my2" class="com.baizhi.action2.MyInterceptor2"></interceptor>
            <!-- 定义一个拦截器栈 -->
            <interceptor-stack name="myStack">
                <interceptor-ref name="my2"></interceptor-ref>
                <interceptor-ref name="my1"></interceptor-ref>
            </interceptor-stack>
        <global-results>
            <result name="error">/error.jsp</result>
        </global-results>
        <action name="aAction" class="com.baizhi.action2.AAction">
            <interceptor-ref name="myStack"></interceptor-ref>
            <result name="success">/index.jsp</result>
        </action>


 

AAction.java

publicclass AAction implements Action{
    public String execute() throws Exception {        System.out.println("this is AAction!!!");
        return"AAction";
    }
}
 


 

MyInterceptor2.java

publicclassMyInterceptor2implements Interceptor {
 
    publicvoid destroy() {
        // TODO Auto-generated method stub
         System.out.println("MyInterceptor2 结束");
    }
 
    publicvoidinit() {
     System.out.println("MyInterceptor2 初始化");
        
    }
 
    public String intercept(ActionInvocation ai) throws Exception {
        System.out.println("this is MyInterceptor22222!!");
        System.out.println(" MyInterceptor2 ai.invoke()="+ai.invoke()+"ai.getAction()="+ai.getAction());
        return"MyInterceptor2";
    }
 
}


 

MyInterceptor.java

package com.baizhi.action2;
 
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
 
public class MyInterceptor implements Interceptor {
    public void destroy() {
        
    }
 
    public void init() {
        
    }
 
    public String intercept(ActionInvocation ai) throws Exception {
        //共有的部分
        //1 让程序通过拦截器
        System.out.println("this is myinterceptor 1111");
        //ai.invoke();
        System.out.println(" MyInterceptor2 ai.invoke()="+ai.invoke()+"ai.getAction()="+ai.getAction());
        //拦截响应
        System.out.println("this is myinterceptor end!!!!");
        //2. 通过ai获取值栈对象
        /*ValueStack vs = ai.getStack();
        vs.setValue("#request.name", "haoge");
        System.out.println(vs.findValue("#request.name"));
        ValueStack vs = ActionContext.getContext().getValueStack();*/
        
        return "MyInterceptor";
    }
 
}


 

 

调用过程

值得注意的是:<default-interceptor-ref>默认拦截器和普通拦截器如果同用一个类,将生成两个代理实例

 

输出结果

this is MyInterceptor22222!!
this is myinterceptor 1111
this is AAction!!!
MyInterceptor2 ai.invoke()=errorai.getAction()=com.baizhi.action2.AAction@1c0b049a
this is myinterceptor end!!!!
MyInterceptor2 ai.invoke()=MyInterceptorai.getAction()=com.baizhi.action2.AAction@1c0b049a


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值