认识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的思想也不过这样。可怜自己学的时候可是死记硬背下
文章评论