spring 代理对象方法增强源码解析
在spring中有两种产生代理对象的方式:AopProxy的子类:Cglib2AopProxy和JdkDynamicAopProxy。1.Jdk主要是:Proxy.newProxyInstance(classLoader, proxiedInterfaces, InvocationHandler); 2.Cglib则是通过Enhancer类来实现的。它们有个相同点就是都有一个回调方法。我们可以在回调方法中对目标方法进行增强。JDK代理对象的回调1.public Object invoke(Object proxy, Method method, Object[] 2.args) throws Throwable { 3. MethodInvocation invocation = null; 4. Object oldProxy = null; 5. boolean setProxyContext = false; 6. TargetSource targetSource = 7.this.advised.targetSource; 8. Class targetClass = null; 9. Object target = null; 10. try { 11. if (!this.equalsDefined && 12.AopUtils.isEqualsMethod(method)) { 13. // The target does not implement the 14.equals(Object) method itself. 15. return equals(args[0]); 16. } 17. if (!this.hashCodeDefined && 18.AopUtils.isHashCodeMethod(method)) { 19. // The target does not implement the 20.hashCode() method itself. 21. return hashCode(); 22. } 23. if (!this.advised.opaque && 24.method.getDeclaringClass().isInterface() && 25. 26.method.getDeclaringClass().isAssignableFrom(Advised.class)) 27.{ 28. // Service invocations on 29.ProxyConfig with the proxy config... 30. return 31.AopUtils.invokeJoinpointUsingReflection(this.advised, 32.method, args); 33. } 34. Object retVal = null; 35. if (this.advised.exposeProxy) { 36. // Make invocation available if 37.necessary. 38. oldProxy = 39.AopContext.setCurrentProxy(proxy); 40. setProxyContext = true; 41. } 42. /** 43. * May be null. Get as late as possible to 44.minimize the time we "own" the 45. * target, in case it comes from a pool. 46. */ 47. //得到目标对象的地方。 48. target = targetSource.getTarget(); 49. if (target != null) { 50. targetClass = target.getClass(); 51. } 52. // Get the interception chain for this 53.method. 54. // 这里获得定义好的拦截器链。 55. List chain = 56.this.advised.getInterceptorsAndDynamicInterception 57.Advice(method, targetClass); 58. /** 59. * Check whether we have any advice. If we 60.don't, we can fallback on 61. * direct reflective invocation of the 62.target, and avoid creating a MethodInvocation. 63. */ 64. 65. // 66.如果没有设定拦截器,那么我们就直接调用target的对应方法。 67. if (chain.isEmpty()) { 68. /** 69. * We can skip creating a 70.MethodInvocation: just invoke the target directly 71. * Note that the final invoker must 72.be an InvokerInterceptor so we 73. * know it does nothing but a 74.reflective operation on the target, and no hot 75. * swapping or fancy proxying. 76. */ 77. retVal = 78.AopUtils.invokeJoinpointUsingReflection(target, method, 79.args); 80. } 81. else { 82. // We need to create a method 83.invocation... 84. /** 85. * 86.如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相 87.应方法, 88. * 89.通过构造一个ReflectiveMethodInvocation来实现,下面我们会看 90. * 91.这个ReflectiveMethodInvocation类的具体实现。 92. */ 93. invocation = new 94.ReflectiveMethodInvocation(proxy, target, method, 95. args, targetClass, chain); 96. // Proceed to the joinpoint through 97.the interceptor chain. 98. //沿着拦截器链继续前进。 99. retVal = invocation.proceed(); 100. } 101. 102. // Massage return value if necessary. 103. if (retVal != null && retVal == target && 104.method.getReturnType(). 105. isInstance(Proxy) && 106.!RawTargetAccess.class.isAssignableFrom 107. (method.getDeclaringClass())) { 108. /** 109. * Special case: it returned "this" 110.and the return type of the method 111. * is type-compatible. Note that we 112.can't help if the target sets 113. * a reference to itself in another 114.returned object. 115. */ 116. retVal = Proxy; 117. } 118. return retVal; 119. } 120. finally { 121. if (target != null && 122.!targetSource.isStatic()) { 123. // Must have come from TargetSource. 124. targetSource.releaseTarget(target); 125. } 126. if (setProxyContext) { 127. // Restore old proxy. 128. 129.AopContext.setCurrentProxy(oldProxy); 130. } 131. } 132.} Cglib代理对象的回调方法:1.public Object intercept(Object proxy, Method method, 2.Object[] args, MethodProxy 3.methodProxy) throws Throwable { 4. Object oldProxy = null; 5. boolean setProxyContext = false; 6. Class targetClass = null; 7. Object target = null; 8. try { 9. if (this.advised.exposeProxy) { 10. // Make invocation available if 11.necessary. 12. oldProxy = 13.AopContext.setCurrentProxy(proxy); 14. setProxyContext = true; 15. } 16. /** 17. * May be null. Get as late as 18.possible to minimize the time we 19. * "own" the target, in case it comes from a 20.pool. 21. */ 22. target = getTarget(); 23. if (target != null) { 24. targetClass = target.getClass(); 25. } 26. //从advised中取得配置好的AOP通知。 27. List chain = 28.this.advised.getInterceptorsAndDynamicInterceptionAdvice 29. (method, targetClass); 30. Object retVal = null; 31. /** 32. * Check whether we only have one 33.InvokerInterceptor: that is, 34. * no real advice, but just reflective 35.invocation of the target. 36. */ 37. // 38.如果没有AOP通知配置,那么直接调用target对象的调用方法。 39. if (chain.isEmpty() && 40.Modifier.isPublic(method.getModifiers())) { 41. /** 42. * We can skip creating a 43.MethodInvocation: just invoke the target directly. 44. * Note that the final invoker must 45.be an InvokerInterceptor, so we know 46. * it does nothing but a reflective 47.operation on the target, and no hot 48. * swapping or fancy proxying. 49. */ 50. retVal = methodProxy.invoke(target, 51.args); 52. } 53. else { 54. 55.//通过CglibMethodInvocation来启动advice通知。 56. retVal = new 57.CglibMethodInvocation(proxy, target, method, args, 58. targetClass, chain, methodProxy).proceed(); 59. } 60. retVal = massageReturnTypeIfNecessary(proxy, 61.target, method, retVal); 62. return retVal; 63. } 64. finally { 65. if (target != null) { 66. releaseTarget(target); 67. } 68. if (setProxyContext) { 69. // Restore old proxy. 70. 71.AopContext.setCurrentProxy(oldProxy); 72. } 73. } 74.} 在调用代理目标对象的方法时;都对方法进行了增强。75.//从advised中取得配置好的AOP通知。 76. List chain = 77.this.advised.getInterceptorsAndDynamicInterceptionAdvice (method, targetClass);在这里可以设置不同的拦截器进行不同的业务处理。比如记录日志,事物的开启…这就是Aop的核心。具体是由相关的拦截器完成的。 在jdk,cglib代理类中都有一个拦截链处理器,它们分别是JDK代理类拦截链处理器:133.这个ReflectiveMethodInvocation类的具体实现。 134. */ 135. ReflectiveMethodInvocation invocation = new 136.ReflectiveMethodInvocation(proxy, target, method, 137. args, targetClass, chain); 138. //沿着拦截器链继续前进。 retVal = invocation.proceed();CGLIB代理类拦截链处理器:78.//通过CglibMethodInvocation来启动advice通知。 79. retVal = new 80.CglibMethodInvocation(proxy, target, method, args, 81. targetClass, chain, methodProxy).proceed(); 82. } 83. retVal = massageReturnTypeIfNecessary(proxy, 84.target, method, retVal); JDK代理类拦截链处理器的proceed方法:1.public Object proceed() throws Throwable { 2. // We start with an index of -1 and increment 3.early. 4. /** 5. *如果拦截器链中的拦截器迭代调用完毕,这里开始调用tar 6.get的函数, 7. *这个函数是通过反射机制完成的,具体实现在:AopUtils. 8.invokeJoinpointUsingReflection方法里面。 9. */ 10. if (this.currentInterceptorIndex == 11.this.interceptorsAndDynamicMethod 12.Matchers.size() - 1) { 13. return invokeJoinpoint(); 14. } 15. //这里沿着定义好的 16.interceptorOrInterceptionAdvice链进行处理。 17. Object interceptorOrInterceptionAdvice = 18. this.interceptorsAndDynamicMethodMatchers.get(++this 19..currentInterceptor 20.Index); 21. if (interceptorOrInterceptionAdvice instanceof 22.InterceptorAndDynamic 23.MethodMatcher) { 24. /** 25. * Evaluate dynamic method matcher here: 26.static part will already have 27. * been evaluated and found to match. 28. */ 29. /** 30. 31.*这里对拦截器进行动态匹配的判断,还记得我们前面分析的pointcu 32.t吗? 33. 34.*这里是触发进行匹配的地方,如果和定义的pointcut匹配,那么这 35.个advice将会得到执行。 36. */ 37. InterceptorAndDynamicMethodMatcher dm = 38. (InterceptorAndDynamicMethodMatcher) 39.interceptorOrInterceptionAdvice; 40. if (dm.methodMatcher.matches(this.method, 41.this.targetClass, this.arguments)) { 42. return dm.interceptor.invoke(this); 43. } 44. else { 45. // Dynamic matching failed. 46. // Skip this interceptor and invoke 47.the next in the chain. 48. // 49.如果不匹配,那么proceed会被递归调用,直到所有的拦截器都被运 50.行过为止。 51. return proceed(); 52. } 53. } 1 楼 sweat89 2012-11-05 注意排版行不,,,,看起来就像一坨屎