Spring框架学习[创建AOP代理对象并对目标对象切面拦截](十一)

2014-11-24 03:05:49 · 作者: · 浏览: 5
ew plaincopyprint //CGLIB回调AOP拦截器链 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Class targetClass = null; Object target = null; try { //如果通知器暴露了代理 if (this.advised.exposeProxy) { //设置给定的代理对象为要被拦截的代理 oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //获取目标对象 target = getTarget(); if (target != null) { targetClass = target.getClass(); } //获取AOP配置的通知 Listchain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; //如果没有配置通知 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { //直接调用目标对象的方法 retVal = methodProxy.invoke(target, args); } //如果配置了通知 else { //通过CglibMethodInvocation来启动配置的通知 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } //获取目标对象对象方法的回调结果,如果有必要则封装为代理 retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal); return retVal; } finally { if (target != null) { releaseTarget(target); } if (setProxyContext) { //存储被回调的代理 AopContext.setCurrentProxy(oldProxy); } } }

6.目标对象方法的调用:

通过上面4和5分别对JdkDynamicAopProxy和Cglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们可以看出,当目标对象没有配置通知器时,代理对象直接调用目标对象的方法,下面具体分析直接调用目标对象方法的过程:

(1).JdkDynamicAopProxy直接调用目标对象方法:

JdkDynamicAopProxy中是通过AopUtils.invokeJoinpointUsingReflection方法来直接调用目标对象的方法,源码如下:

[java] view plaincopyprint //通过反射机制直接调用目标对象方法 public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable { try { //通过反射使给定的方法可以访问,主要是对protected和private方法使用,//取消严格访问控制权限的限制 ReflectionUtils.makeAccessible(method); //使用反射机制调用目标对象的方法 return method.invoke(target, args); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex);