Struts2的拦截器模拟

    技术2022-05-20  34

    struts2的核心调用拦截器部分在DefaultActionInvocation中的invoke方法中 代码部分如下

    if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); String interceptorMsg = "interceptor: " + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } } else { resultCode = invokeActionOnly(); }

     

    核心便是这句

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

     

    看了半天想了半天,才发现原来这是用了递归...如果简单点可以如下这么模拟拦截器的功能

    package invocation; public interface PlayerInterface { public void kick(); }

    package invocation; public class Player implements PlayerInterface{ public void kick(){ System.out.println("我要踢球"); } }

    package invocation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Iterator; import java.util.List; public class PlayerHandler implements InvocationHandler { private Object target; private List<String> interceptList; /* 递归的调用拦截器的模拟原理实现,构造handler类时候传入对应的拦截器列表,并初始化遍历,当然只是模拟,struts2不是 * 这么直白的构造方式 */ private Iterator iter; public PlayerHandler(Object target, List<String> interceptList) { this.target = target; this.interceptList = interceptList; /* 遍历赋值 */ iter = interceptList.iterator(); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { /* 递归的调用拦截器的原理模拟实现 */ if(iter.hasNext()){ System.out.println(iter.next()); invoke(proxy, method, args); }else{ System.out.println("---拦截器调用完毕。---"); return method.invoke(target, args); } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("over"); } return null; } public Object createObjectProxy(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), this ); } }

    package invocation; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { /* 真实对象 */ Player p = new Player(); /* 模拟拦截器 */ List<String> interceptorList = new ArrayList<String>(); interceptorList.add("拦截器1"); interceptorList.add("拦截器2"); interceptorList.add("拦截器3"); interceptorList.add("拦截器4"); /* handler处理类 */ PlayerHandler handler = new PlayerHandler(p, interceptorList); PlayerInterface player = (PlayerInterface)handler.createObjectProxy(); player.kick(); } }

     

    如上,简单的模拟了struts2内部调用拦截器的过程。

     

    结果:

    拦截器1拦截器2拦截器3拦截器4---拦截器调用完毕。---我要踢球overoveroveroverover

     


    最新回复(0)