Struts2 中的Aop AOP思想

2013/10/21 2398点热度 0人点赞 0条评论

认识aop还是从了解struts2中的拦截器了解这个思想的,struts2中的拦截可插拔式的配置方式刚开始让我半懂不懂的,只知道按着自己的需要配置就行了。

 前一段时间翻看struts2中的源代码,发现原来struts2中的aop也不过如此。

众所周知,struts2的拦截器是来自于Interceptor接口,或者继承了抽象类AbstractInterceptor。

观看所有的拦截器,实现的intercept(ActionInvocation invocation)方法。

ActionInvocation  又称上Struts2的下文,里面包含了请求的参数和请求携带的不少系统参数。

拦截器验证通过以后执行这行代码。

 return invocation.invoke();

每个拦截器都在执行这行代码。我翻了下ActionInvocation的实现类,有两个,分别是

DefaultActionInvocation和MockActionInvocation

翻看MockActionInvocation中的代码,没有找到invoke()方法,

在DefaultActionInvocation实现类中找到invoke()和一个相关的参数。

 protected Iterator interceptors;//解析struts2的配置文件的时候将所有的拦截器都放到了这里
 
  public String invoke() throws Exception {
        String profileKey = "invoke: ";
        try {
            UtilTimerStack.push(profileKey);

            if (executed) {
                throw new IllegalStateException("Action has already executed");
            }

            if (interceptors.hasNext()) {//这里迭代了所有的interceptor
                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();
            }

            // this is needed because the result will be executed, then control will return to the Interceptor, which will
            // return above and flow through again
            if (!executed) {
                if (preResultListeners != null) {
                    for (Object preResultListener : preResultListeners) {
                        PreResultListener listener = (PreResultListener) preResultListener;

                        String _profileKey = "preResultListener: ";
                        try {
                            UtilTimerStack.push(_profileKey);
                            listener.beforeResult(this, resultCode);
                        }
                        finally {
                            UtilTimerStack.pop(_profileKey);
                        }
                    }
                }

                // now execute the result, if we're supposed to
                if (proxy.getExecuteResult()) {
                    executeResult();
                }

                executed = true;
            }

            return resultCode;
        }
        finally {
            UtilTimerStack.pop(profileKey);
        }
    }

再结合下面的代码

public String intercept(ActionInvocation invocation) throws Exception {
     return invocation.invoke();//原来这里相当于一个递归方法了,一下子恍然大悟。
}

看到这里,我们就不难的把struts2中的aop的思想抽出来使用

/**核心接口*/
public interface baseA{
   public  String invoke() throws Exception;
}
public class BaseB implements baseA{
    protected Iterator interceptors;//所有可插拔的参数
    public  String invoke() throws Exception{
         String returnStr=null;
         if (interceptors.hasNext()) {
             returnStr="执行所拦截,或者说可配置的方法()";//在外面包装都执行完了,才执行最后的目标方法
         }else{
             returnStr="执行目标最后要执行的方法()";
         }
         return returnStr;
    }
}
//既然你想实现可插拔的效果,那你必须遵循我的定义的规范,也就是Interceptor了
public interface Interceptor extends Serializable {
    public String intercept(baseA basea) throws Exception;//这个是我定义的规范,你必须实现他,才可以使用我的可插拔的方式,而且你实现我这个接口的时候最后验证过了必须执行 basea.invoke();这个方法
}

好吧,到此struts2中的aop已经抽出来了,想想aop的思想也不过这样。可怜自己学的时候可是死记硬背下

yxkong

这个人很懒,什么都没留下

文章评论