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. }

猜你喜欢

转载自m635674608.iteye.com/blog/1715243
今日推荐