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

packagecom.ml.test;

publicinterfaceManager{

publicvoidmodify();

}

packagecom.ml.test;

publicclassManagerImplimplementsManager{

@Override

publicvoidmodify(){

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();
}
}

三.执行结果:

dosomethingbeforemethod

*******modify()方法被调用

dosomethingaftermethod

四.机制分析:

Proxy.(ClassLoaderloader,Class<?>[]interfaces,InvocationHandlerh)做了以下几件事.

(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.importjava.lang.reflect.InvocationHandler;

2.importjava.lang.reflect.Method;

3.importjava.lang.reflect.Proxy;

4.importjava.lang.reflect.UndeclaredThrowableException;

5.

6.publicfinalclass$Proxy0extendsProxyimplementsManager{

7.

8.privatestaticMethodm1;

9.privatestaticMethodm0;

10.privatestaticMethodm3;

11.privatestaticMethodm2;

12.

13.static{

14.try{

15.m1=Class.forName("java.lang.Object").getMethod("equals",

16.newClass[]{Class.forName("java.lang.Object")});

17.m0=Class.forName("java.lang.Object").getMethod("hashCode",

18.newClass[0]);

19.m3=Class.forName("com.ml.test.Manager").getMethod("modify",

20.newClass[0]);

21.m2=Class.forName("java.lang.Object").getMethod("toString",

22.newClass[0]);

23.}catch(NoSuchMethodExceptionnosuchmethodexception){

24.thrownewNoSuchMethodError(nosuchmethodexception.getMessage());

25.}catch(ClassNotFoundExceptionclassnotfoundexception){

26.thrownewNoClassDefFoundError(classnotfoundexception.getMessage());

27.}

28.}

29.

30.public$Proxy0(InvocationHandlerinvocationhandler){

31.super(invocationhandler);

32.}

33.

34.@Override

35.publicfinalbooleanequals(Objectobj){

36.try{

37.return((Boolean)super.h.invoke(this,m1,newObject[]{obj}))

38..booleanValue();

39.}catch(Throwablethrowable){

40.thrownewUndeclaredThrowableException(throwable);

41.}

42.}

43.

44.@Override

45.publicfinalinthashCode(){

46.try{

47.return((Integer)super.h.invoke(this,m0,null)).intValue();

48.}catch(Throwablethrowable){

49.thrownewUndeclaredThrowableException(throwable);

50.}

51.}

52.

53.publicfinalvoidmodify(){

54.try{

55.super.h.invoke(this,m3,null);

56.return;

57.}catch(Errore){

58.}catch(Throwablethrowable){

59.thrownewUndeclaredThrowableException(throwable);

60.}

61.}

62.

63.@Override

64.publicfinalStringtoString(){

65.try{

66.return(String)super.h.invoke(this,m2,null);

67.}catch(Throwablethrowable){

68.thrownewUndeclaredThrowableException(throwable);

69.}

70.}

71.}

importjava.lang.reflect.InvocationHandler;

importjava.lang.reflect.Method;

importjava.lang.reflect.Proxy;

importjava.lang.reflect.UndeclaredThrowableException;

publicfinalclass$Proxy0extendsProxyimplementsManager{

privatestaticMethodm1;

privatestaticMethodm0;

privatestaticMethodm3;

privatestaticMethodm2;

static{

try{

m1=Class.forName("java.lang.Object").getMethod("equals",

newClass[]{Class.forName("java.lang.Object")});

m0=Class.forName("java.lang.Object").getMethod("hashCode",

newClass[0]);

m3=Class.forName("com.ml.test.Manager").getMethod("modify",

newClass[0]);

m2=Class.forName("java.lang.Object").getMethod("toString",

newClass[0]);

}catch(NoSuchMethodExceptionnosuchmethodexception){

thrownewNoSuchMethodError(nosuchmethodexception.getMessage());

}catch(ClassNotFoundExceptionclassnotfoundexception){

thrownewNoClassDefFoundError(classnotfoundexception.getMessage());

}

}

public$Proxy0(InvocationHandlerinvocationhandler){

super(invocationhandler);

}

@Override

publicfinalbooleanequals(Objectobj){

try{

return((Boolean)super.h.invoke(this,m1,newObject[]{obj}))

.booleanValue();

}catch(Throwablethrowable){

thrownewUndeclaredThrowableException(throwable);

}

}

@Override

publicfinalinthashCode(){

try{

return((Integer)super.h.invoke(this,m0,null)).intValue();

}catch(Throwablethrowable){

thrownewUndeclaredThrowableException(throwable);

}

}

publicfinalvoidmodify(){

try{

super.h.invoke(this,m3,null);

return;

}catch(Errore){

}catch(Throwablethrowable){

thrownewUndeclaredThrowableException(throwable);

}

}

@Override

publicfinalStringtoString(){

try{

return(String)super.h.invoke(this,m2,null);

}catch(Throwablethrowable){

thrownewUndeclaredThrowableException(throwable);

}

}

}

接着把得到的$Proxy0实例强制转换成Manager.

当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.

在modify方法中,调用父类Proxy中的h的invoke()方法.

即InvocationHandler.invoke();

相关推荐