`

jdk动态代理(Proxy,InvocationHandler),含$Proxy0源码

阅读更多
一.相关类及其方法:

java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(详见api文档)

java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
(详见api文档)

二.源代码:

被代理对象的接口及实现类:
Java代码  收藏代码

  
1. package com.ml.test;  
   2.   
   3. public interface Manager {  
   4. public void modify();  
   5. }  
   6.   
   7. package com.ml.test;  
   8.   
   9. public class ManagerImpl implements Manager {  
  10.   
  11. @Override  
  12. public void modify() {  
  13.    System.out.println("*******modify()方法被调用");  
  14. }  
  15. }  


package com.ml.test;

public interface Manager {
public void modify();
}

package com.ml.test;

public class ManagerImpl implements Manager {

@Override
public void modify() {
   System.out.println("*******modify()方法被调用");
}
}


业务代理类:
Java代码  收藏代码

 
 1. package com.ml.test;  
   2.   
   3. import java.lang.reflect.InvocationHandler;  
   4. import java.lang.reflect.Method;  
   5.   
   6. public class BusinessHandler implements InvocationHandler {  
   7.   
   8. private Object object = null;  
   9.   
  10. public BusinessHandler(Object object) {  
  11.    this.object = object;  
  12. }  
  13.   
  14. @Override  
  15. public Object invoke(Object proxy, Method method, Object[] args)  
  16.     throws Throwable {  
  17.    System.out.println("do something before method");  
  18.    Object ret = method.invoke(this.object, args);  
  19.    System.out.println("do something after method");  
  20.    return ret;  
  21.   
  22. }  
  23. }  


package com.ml.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class BusinessHandler implements InvocationHandler {

private Object object = null;

public BusinessHandler(Object object) {
   this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
   System.out.println("do something before method");
   Object ret = method.invoke(this.object, args);
   System.out.println("do something after method");
   return ret;

}
}




客户端类:
Java代码  收藏代码

  
1. package com.ml.test;  
   2. import java.lang.reflect.Proxy;  
   3. public class Client {  
   4.   
   5. public static void main(String[] args) {  
   6.    // 元对象(被代理对象)  
   7.    ManagerImpl managerImpl = new ManagerImpl();  
   8.   
   9.    // 业务代理类  
  10.    BusinessHandler securityHandler = new BusinessHandler(managerImpl);  
  11.   
  12.    // 获得代理类($Proxy0 extends Proxy implements Manager)的实例.  
  13.    Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl  
  14.      .getClass().getClassLoader(), managerImpl.getClass()  
  15.      .getInterfaces(), securityHandler);  
  16.   
  17.    managerProxy.modify();  
  18. }  
  19. }  

package com.ml.test;
import java.lang.reflect.Proxy;
public class Client {

public static void main(String[] args) {
   // 元对象(被代理对象)
   ManagerImpl managerImpl = new ManagerImpl();

   // 业务代理类
   BusinessHandler securityHandler = new BusinessHandler(managerImpl);

   // 获得代理类($Proxy0 extends Proxy implements Manager)的实例.
   Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl
     .getClass().getClassLoader(), managerImpl.getClass()
     .getInterfaces(), securityHandler);

   managerProxy.modify();
}
}


三.执行结果:
do something before method
*******modify()方法被调用
do something after method

四.机制分析:

Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
Java代码  收藏代码

 
 1. class Proxy{  
   2.    InvocationHandler h=null;  
   3.    protected Proxy(InvocationHandler h) {  
   4.     this.h = h;  
   5.    }  
   6.    ...  
   7. }  

class Proxy{
   InvocationHandler h=null;
   protected Proxy(InvocationHandler h) {
    this.h = h;
   }
   ...
}






下面是本例的$Proxy0类的源码(好不容易才把它提出来,改了JRE源码,打印出字节码,把字节码保存为class文件,并反编译class文件):


Java代码  收藏代码

   1. import java.lang.reflect.InvocationHandler; 
   2. import java.lang.reflect.Method; 
   3. import java.lang.reflect.Proxy; 
   4. import java.lang.reflect.UndeclaredThrowableException; 
   5.  
   6. public final class $Proxy0 extends Proxy implements Manager { 
   7.  
   8. private static Method m1; 
   9. private static Method m0; 
  10. private static Method m3; 
  11. private static Method m2; 
  12.  
  13. static { 
  14.    try { 
  15.     m1 = Class.forName("java.lang.Object").getMethod("equals", 
  16.       new Class[] { Class.forName("java.lang.Object") }); 
  17.     m0 = Class.forName("java.lang.Object").getMethod("hashCode", 
  18.       new Class[0]); 
  19.     m3 = Class.forName("com.ml.test.Manager").getMethod("modify", 
  20.       new Class[0]); 
  21.     m2 = Class.forName("java.lang.Object").getMethod("toString", 
  22.       new Class[0]); 
  23.    } catch (NoSuchMethodException nosuchmethodexception) { 
  24.     throw new NoSuchMethodError(nosuchmethodexception.getMessage()); 
  25.    } catch (ClassNotFoundException classnotfoundexception) { 
  26.     throw new NoClassDefFoundError(classnotfoundexception.getMessage()); 
  27.    } 
  28. } 
  29.  
  30. public $Proxy0(InvocationHandler invocationhandler) { 
  31.    super(invocationhandler); 
  32. } 
  33.  
  34. @Override 
  35. public final boolean equals(Object obj) { 
  36.    try { 
  37.     return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) 
  38.       .booleanValue(); 
  39.    } catch (Throwable throwable) { 
  40.     throw new UndeclaredThrowableException(throwable); 
  41.    } 
  42. } 
  43.  
  44. @Override 
  45. public final int hashCode() { 
  46.    try { 
  47.     return ((Integer) super.h.invoke(this, m0, null)).intValue(); 
  48.    } catch (Throwable throwable) { 
  49.     throw new UndeclaredThrowableException(throwable); 
  50.    } 
  51. } 
  52.  
  53. public final void modify() { 
  54.    try { 
  55.     super.h.invoke(this, m3, null); 
  56.     return; 
  57.    } catch (Error e) { 
  58.    } catch (Throwable throwable) { 
  59.     throw new UndeclaredThrowableException(throwable); 
  60.    } 
  61. } 
  62.  
  63. @Override 
  64. public final String toString() { 
  65.    try { 
  66.     return (String) super.h.invoke(this, m2, null); 
  67.    } catch (Throwable throwable) { 
  68.     throw new UndeclaredThrowableException(throwable); 
  69.    } 
  70. } 
  71. } 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Manager {

private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
   try {
    m1 = Class.forName("java.lang.Object").getMethod("equals",
      new Class[] { Class.forName("java.lang.Object") });
    m0 = Class.forName("java.lang.Object").getMethod("hashCode",
      new Class[0]);
    m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
      new Class[0]);
    m2 = Class.forName("java.lang.Object").getMethod("toString",
      new Class[0]);
   } catch (NoSuchMethodException nosuchmethodexception) {
    throw new NoSuchMethodError(nosuchmethodexception.getMessage());
   } catch (ClassNotFoundException classnotfoundexception) {
    throw new NoClassDefFoundError(classnotfoundexception.getMessage());
   }
}

public $Proxy0(InvocationHandler invocationhandler) {
   super(invocationhandler);
}

@Override
public final boolean equals(Object obj) {
   try {
    return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
      .booleanValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final int hashCode() {
   try {
    return ((Integer) super.h.invoke(this, m0, null)).intValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

public final void modify() {
   try {
    super.h.invoke(this, m3, null);
    return;
   } catch (Error e) {
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final String toString() {
   try {
    return (String) super.h.invoke(this, m2, null);
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
}


接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();
分享到:
评论
1 楼 飞鸿247 2012-07-30  
    

相关推荐

    JDK动态代理(powernode CD2207 video)(教学视频+源代码)

    JDK动态代理(powernode CD2207 video)(教学视频+源代码) JDK动态代理(powernode CD2207 video) 一、动态代理 1.1JDK动态代理 1.1.1 proxy 1.1.2 InvocationHandler 1.1.3 创建一个Maven项目 1.1.4 导入Spring...

    JDK的动态代理(powernode 文档)(源代码)

    JDK的动态代理(powernode 文档)(源代码) JDK的动态代理(powernode 文档) 一、动态代理 1.1JDK动态代理 1.1.1 proxy 1.1.2 InvocationHandler 1.1.3 创建一个Maven项目 1.1.4 导入Spring的相关依赖 1.1.5 修改...

    Java面向对象系列[v1.0.0][使用反射生成动态代理]

    在Java的java.lang.reflect包里有个Proxy类和一个InvocationHandler接口,通过使用他们可以生成JDK动态代理类或动态代理对象 使用Proxy和InvocationHandler创建动态代理 Proxy提供了用于创建动态代理类和代理对象的...

    AOP的实现机制

    Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。使用动态代理实现AOP需要有四个角色:被代理的类,被代理类的接口,织入器,和InvocationHandler,而织入器使用接口反射机制生成一个代理类...

    spring动态代理原理

    通过代码了解springaop原理,代码采用jdk的动态代理相关类Proxy、InvocationHandler解释动态代理模式

    类似spring Aop的Proxy封装

    * 动态代理升级类测试 * @author FANGJINXIN * */ public class ProxyUpTest { public static void main(String[] args) { UserMgr userMgr = new UserMgrImpl(); Object proxy = ProxyUp.newProxy...

    demo:java生产项目常用的demo

    模仿jdk proxy自己实现动态代理: 核心:实现动态代理的Proxy类 , 实现动态代理的InvocationHandler类重写invoke方法实现. 二.spring 1.spring ioc 1.1.spring容器 1.1.1.BeanFactory 常用实现类:...

    摩西设计

    JDKProxy,JDKInvocationHandler,是代理类的定义和实现,这部分也就是抽象⼯⼚的另外⼀种实现⽅式。通过这样的⽅式可以很好的把放置操作Redis的⽅法进⾏代理操作,通过控制不同的⼊参对象,控制缓存的使坯。 ...

    vs没报错leetcode报错-leetcode:leetcode

    动态代理(JDK代理,借口代理) package basicKnowledge.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /* * JDK 动态代理 * */ ...

    java 实现AOP

     JDK1.2以后提供了动态代理的支持,程序员通过实现java.lang.reflect.InvocationHandler接口提供一个执行处理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行商业方法,在商业方法被...

    Java 高级特性.doc

    这个是JDK 增加的新特性的用法! public static void loop(int x,int... args ) { //这里的参数一定要以这样的形式输入 for(int i:args) { System.out.println(i); } } 3.枚举 写枚举技巧: 1. enum Gender{...

    疯狂JAVA讲义

    1.4.1 安装JDK 8 学生提问:不是说JVM是运行Java程序的虚拟机吗?那JRE和JVM的关系是怎样的呢? 8 学生提问:为什么不安装公共JRE系统呢? 9 1.4.2 设置PATH环境变量 10 学生提问:为什么选择设置用户变量,用户...

Global site tag (gtag.js) - Google Analytics