`
m635674608
  • 浏览: 5079703 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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. }
  • 描述: 相关拦截器
  • 大小: 91.4 KB
1
4
分享到:
评论
1 楼 sweat89 2012-11-05  
注意排版行不,,,,看起来就像一坨屎

相关推荐

    Spring源码解析.pdf

    ### Spring源码解析知识点 #### 一、Spring IoC 容器详解 ##### 1. BeanFactory —— 最...掌握Spring的源码解析不仅可以帮助开发者更好地理解和使用Spring框架,还能提高解决问题的能力,增强软件开发的整体质量。

    Spring5 源码分析(第 2 版)-某Tom老师

    在Spring5中,DI仍然是核心设计模式,它使得对象之间的依赖关系得以解耦,增强了代码的可测试性和可维护性。Tom老师的文档会详细阐述IoC容器是如何实现DI的,包括Bean的生命周期管理、自动装配以及各种类型的Bean...

    spring源码解析和mybatis学习

    6. **Spring源码分析**:通过阅读源码,理解Spring框架的工作原理,增强对框架的深入理解。 接下来,我们转向MyBatis,这是一个轻量级的持久层框架,它提供了灵活的SQL映射机制,使得数据库操作变得简单。"MyBatis3...

    spring源码深入解析

    《Spring源码深入解析》是一本深度探讨Spring框架核心机制的文档,主要针对Spring5版本...文档《Spring源码解析-tom.docx》应包含了上述各方面的详细解读,对于希望深入了解Spring的开发者来说,是一份宝贵的参考资料。

    spring源码分析

    `ProxyFactoryBean`和`AspectJAutoProxyCreator`是AOP实现的两个关键类,它们生成代理对象并执行切面逻辑。 在Spring MVC和AOP的基础上,Spring还支持与ORM框架的集成,如Hibernate。Spring通过`HibernateTemplate`...

    Spring Aop 引用新功能 源码

    在运行时,Spring会创建一个代理对象,这个代理对象不仅包含了目标对象的所有行为,还额外实现了`SecuredInterface`。 **使用场景** 引入在以下场景中尤其有用: 1. **安全性增强** - 添加认证和授权功能,如`...

    spring源码分析(1-10)

    Spring AOP通过动态代理(JDK Proxy或CGLIB)创建目标对象的代理,实现切面的织入。Pointcut定义切入点,Advice定义增强处理,Advisor结合两者,Aspect则封装了多个Advisor。 6. **Spring 声明式事务处理**:基于...

    SpringAOP的源码解析.doc

    在Spring AOP执行过程中,当调用被代理对象的方法时,实际上会触发AOP代理的拦截逻辑,执行相应的通知,并在适当的时候调用实际的目标方法。 总的来说,Spring AOP通过动态代理机制,实现了对目标对象的透明拦截,...

    Spring AOP 源码解析思维导图

    此外,还可以通过expose-proxy属性来控制是否将代理对象暴露到ThreadLocal中,以便在目标类的内部方法中可以方便地访问到代理对象。 在Spring AOP中,还可以通过实现BeanPostProcessor接口来自定义bean的创建过程,...

    spring-source-4.2.4源码

    《Spring框架4.2.4源码解析》 Spring框架是Java领域中广泛使用的轻量级开源框架,它以其模块化、松耦合的设计理念,为开发者提供了强大的企业级应用开发支持。本篇将深入探讨Spring 4.2.4版本的源码,通过分析各个...

    Spring-4.3源码

    Spring 4.3对MVC进行了优化,包括更好的类型安全的模型绑定、增强的异常处理和视图解析。`@RequestMapping`、`@GetMapping`、`@PostMapping`等注解用于映射HTTP请求到处理方法。`ModelAndView`或`Model`接口用于向...

    Spring CGLlB动态代理实现过程解析

    "Spring CGLlB动态代理实现过程解析" Spring CGLIB动态代理是Spring框架中的一种动态代理机制,它通过CGLIB(Code Generation Library)生成代理类来实现动态代理。CGLIB是一个高性能的开源代码生成包,能够在运行...

    dubbo源码解析2

    ### Dubbo源码解析2 #### 一、源码阅读路径 在开始深入解析Dubbo源码之前,首先需要明确的是,Dubbo虽然代码量不算庞大,但是它涉及的技术领域非常广泛,对于初学者来说,可能需要具备一定的前置知识才能更好地...

    spring 源码解析

    《Spring源码解析》系列文章深入探讨了Spring框架的核心组件和工作原理,为读者提供了丰富的技术洞察。以下是对这些主题的详细解读: 1. **Spring MVC**:Spring MVC是Spring框架的一部分,它提供了构建Web应用程序...

    spring-demo:spring原始解析-源码解析

    《Spring框架源码解析——深度探索spring-demo》 在IT领域,Spring框架是Java开发者最为广泛应用的轻量级框架之一,其强大的功能和灵活的设计深受赞誉。本文将深入探讨"spring-demo:spring原始解析"这一主题,带领...

    官方原版源码spring-framework-5.2.3.RELEASE.zip

    再比如`AOPProxy`和`Advised`,它们是实现AOP的关键组件,用于创建代理对象并管理增强(advice)。 深入学习Spring源码,不仅能够帮助我们理解其工作原理,还能提升我们在实际项目中的问题排查能力。例如,当我们...

    spring源码解析

    接下来我将详细介绍Spring框架中几个核心模块的源码解析。 首先,Spring的依赖注入(DI)是Spring框架的核心特性之一,它通过容器来管理对象之间的依赖关系。Spring容器在创建对象时,会自动注入这些对象所需的依赖...

    Spring源码解析

    Spring AOP主要基于动态代理技术实现,通过创建代理对象来拦截目标方法调用,从而实现对目标方法的增强。 - **代理模式**:Spring AOP支持两种类型的代理:JDK动态代理和CGLIB代理。 - **JDK动态代理**:适用于...

    Spring4.x源码

    AOP通过动态代理技术(JDK Proxy或CGLIB)实现,可以在不修改原有代码的情况下,插入额外的功能,增强了代码的可扩展性。 3. **Bean工厂与ApplicationContext** Spring的Bean工厂是对象管理的基础,它负责创建、...

Global site tag (gtag.js) - Google Analytics