======================================================================
代理类生成之后再调用目标方法时就会调用invoke方法
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
======================================================================

【Spring AOP的底层实现技术 Proxy InvocationHandler】【 http://blog.csdn.net/sup_heaven/article/details/6898292 】

【动态代理模式】分离横切关注点
InvocationHandler反射机制:java.lang.reflect.Method,java.lang.reflact.Proxy
InvocationHandler:

public Object invoke ( Object proxy,Method method, Object[] args)
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable
 
【Java动态代理核心】
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;

【AOP代理对象的生成】
两种方式:JDK Proxy代理接口,CGLib扩展类。
JdkDynamicAopProxy类:创建代理,Proxy.newProxyInstance( classLoader, proxiedInterfaces, this );


上面我们看到了在Spring中通过ProxyFactoryBean实现AOP功能的第一步,得到AopProxy代理对象的基本过程,以及通过使用 JDK和CGLIB最终产生AopProxy代理对象的实现原理。下面我们看看AopProxy代理对象的拦截机制是怎样发挥作用和实现AOP功能的。在 JdkDynamicAopProxy中生成Proxy对象时,我们回顾一下它的AopProxy代理对象的生成调用,如下所示。

  1. Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

这 里的this参数对应的是InvocationHandler对象,InvocationHandler是JDK定义的反射类的一个接口,这个接口定义了 invoke方法,而这个invoke方法是作为JDKProxy代理对象进行拦截的回调入口出现的。我们看到,在JdkDynamicAopProxy 实现了InvocationHandler接口,也就是说当Proxy对象的代理方法被调用时,JdkDynamicAopProxy的invoke方法作为Proxy对象的回调函数而被触发,从而通过invoke的具体实现,来完成对目标对象方法调用的拦截或者说功能增强的工作。

下 面我们看看JdkDynamicAopProxy的invoke方法实现,如代码清单3-18所示。可以看到,对Proxy对象完成的代理设置是在 invoke方法中完成的,这些设置包括获取目标对象、拦截器链,同时把这些对象作为输入,创建了ReflectiveMethodInvocation 对象,通过这个ReflectiveMethodInvocation对象来完成对AOP功能实现的封装。

在这个invoke方法中,包含了一个完整的拦截器链对目标对象的拦截过程,比如获得拦截器链并对其中的拦截器进行配置,逐个运行拦截器链里的拦截增强,直到最后对目标对象方法的运行,等等。

代码清单3-18  AopProxy代理对象的回调

  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. method.getDeclaringClass().isAssignableFrom(Advised.class))
  26. {
  27. // Service invocations on
  28. ProxyConfig with the proxy config...
  29. return
  30. AopUtils.invokeJoinpointUsingReflection(this.advised,
  31. method, args);
  32. }
  33. Object retVal = null;
  34. if (this.advised.exposeProxy) {
  35. // Make invocation available if
  36. necessary.
  37. oldProxy =
  38. AopContext.setCurrentProxy(proxy);
  39. setProxyContext = true;
  40. }
  41. /**
  42. * May be null. Get as late as possible to
  43. minimize the time we "own" the
  44. * target, in case it comes from a pool.
  45. */
  46. //得到目标对象的地方。
  47. target = targetSource.getTarget();
  48. if (target != null) {
  49. targetClass = target.getClass();
  50. }
  51. // Get the interception chain for this
  52. method.
  53. // 这里获得定义好的拦截器链。
  54. List<Object> chain =
  55. this.advised.getInterceptorsAndDynamicInterception
  56. Advice(method, targetClass);
  57. /**
  58. * Check whether we have any advice. If we
  59. don't, we can fallback on
  60. * direct reflective invocation of the
  61. target, and avoid creating a MethodInvocation.
  62. */
  63. //
  64. 如果没有设定拦截器,那么我们就直接调用target的对应方法。
  65. if (chain.isEmpty()) {
  66. /**
  67. * We can skip creating a
  68. MethodInvocation: just invoke the target directly
  69. * Note that the final invoker must
  70. be an InvokerInterceptor so we
  71. * know it does nothing but a
  72. reflective operation on the target, and no hot
  73. * swapping or fancy proxying.
  74. */
  75. retVal =
  76. AopUtils.invokeJoinpointUsingReflection(target, method,
  77. args);
  78. }
  79. else {
  80. // We need to create a method
  81. invocation...
  82. /**
  83. *
  84. 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相
  85. 应方法,
  86. *
  87. 通过构造一个ReflectiveMethodInvocation来实现,下面我们会看
  88. *
  89. 这个ReflectiveMethodInvocation类的具体实现。
  90. */
  91. invocation = new
  92. ReflectiveMethodInvocation(proxy, target, method,
  93. args, targetClass, chain);
  94. // Proceed to the joinpoint through
  95. the interceptor chain.
  96. //沿着拦截器链继续前进。
  97. retVal = invocation.proceed();
  98. }
  99. // Massage return value if necessary.
  100. if (retVal != null && retVal == target &&
  101. method.getReturnType().
  102. isInstance(Proxy) &&
  103. !RawTargetAccess.class.isAssignableFrom
  104. (method.getDeclaringClass())) {
  105. /**
  106. * Special case: it returned "this"
  107. and the return type of the method
  108. * is type-compatible. Note that we
  109. can't help if the target sets
  110. * a reference to itself in another
  111. returned object.
  112. */
  113. retVal = Proxy;
  114. }
  115. return retVal;
  116. }
  117. finally {
  118. if (target != null &&
  119. !targetSource.isStatic()) {
  120. // Must have come from TargetSource.
  121. targetSource.releaseTarget(target);
  122. }
  123. if (setProxyContext) {
  124. // Restore old proxy.
  125. AopContext.setCurrentProxy(oldProxy);
  126. }
  127. }
  128. }

InvocationHandler的更多相关文章

  1. java中InvocationHandler 用于实现代理。

    以下的内容部分参考了网络上的内容,在此对原作者表示感谢! Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandler接口中的 ...

  2. java 动态代理范例 InvocationHandler与Proxy

    java 动态代理范例 InvocationHandler与Proxy,拦截与代理 java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxy ...

  3. java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码

    java 动态代理深度学习, 一.相关类及其方法: java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定 ...

  4. java 动态代理学习(Proxy,InvocationHandler)

    前几天看到java的动态代理机制,不知道是啥玩意,然后看了看.死活不知道 invoke(Object proxy, Method m, Object[] args)种的proxy是个什么东西,放在这里 ...

  5. 动态代理 Proxy InvocationHandler

      前奏 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常 ...

  6. InvocationHandler中invoke()方法的调用问题

    转InvocationHandler中invoke()方法的调用问题 Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandl ...

  7. Proxy是在什么时候调用InvocationHandler的invoke方法的

    最近看到spring的动态代理,扒到深处看到时 Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);看到这一句,顿时比较懵逼,还是 ...

  8. 基于接口的 InvocationHandler 动态代理(换种写法)

    InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each p ...

  9. InvocationHandler和Proxy(Class)的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

随机推荐

  1. java生成简单Excel工作薄

    前言: 代码都是建立在实际需求上的,上周做完一个调外部电影券接口的项目,这周产品又要excel表格,大致内容为:券所属影院.图片URL.等信息制作为excel表格,把每次同步过来的数据给他分析. jx ...

  2. svn log 不显示日志的问题

    在你配好了Xcode里的SourceControl之后提交代码回复代码都很方便,可是为什么在Xcode上提交的log,在svn下面显示不出来! 解决办法是:在命令行下,先 svn update 一下, ...

  3. [Everyday Mathematic]20150216

    设 $A,B,C$ 是同阶方阵, 试证: $$\bex (A-B)C=BA^{-1}\ra C(A-B)=A^{-1}B. \eex$$

  4. bjfu1277 简单递归

    比较简单的递归问题.对于第k时刻的图形,可以平均分成四块,左上,右上,左下这三块的图形是一模一样的,右下的那一块不包含红毛僵尸,所以把那三块里的加起来就是结果了. /* * Author : ben ...

  5. linux笔记_20150825_linux下的软件工具唠叨下

    这些都是书上看到的,有些工具我也没有完全用过.先记下来再说.闲着也是闲着. 1.linux下常见的语言及编程环境:c/c++/java/perl/fortan等. 2.图形环境:gnome/kde/g ...

  6. spring初探1

    spring初探1 关于新建对象,对象依赖的三种方式比较 场景 某个交易的业务组建拆分,为原先的功能模块新写了一个业务组件 使用new. 修改上层代码的对象生成部分( 如果不是面向接口编程,简直就是灾 ...

  7. 多线程的Python 教程--“贪吃蛇”

    本指南的里代码可以在这里下载:  threadworms.py ,或者从  GitHub.代码需要  Python 3 或 Python 2 ,同时也需要安装  Pygame . 点击查看大版本图片 ...

  8. mybatis源码学习: 动态代理的应用(慢慢改)

    动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system. ...

  9. c/c++ 数字转成字符串, 字符串转成数字

    c/c++ 数字转成字符串, 字符串转成数字 ------转帖 数字转字符串: 用C++的streanstream: #include <sstream> #Include <str ...

  10. Firefox 对条件判断语句块内的函数声明的处理与其他浏览器有差异

    标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { Func ...