您的位置:首页 > 编程语言 > Java开发

Java动态代理借助Proxy与InvocationHandler实现

2012-08-10 16:15 483 查看
Java 自带实现类的动态代理机制是基于接口(interface)的!也就是说类A要能实现动态代理,首先要实现一个接口proxyInterface(proxyInterface是随意命名的,这里代表要用作构建代理的接口),然后再在接口proxyInterface的基础上构建代理类。

 构建方法:

Java 使用自带的Proxy类,以及InvocationHandler接口,可以实现动态的构造一个类A的代理示例对象A1,

(一)实例:

(1)首先建一个接口ProxyInterface

//用作构建代理的接口

package com.langsin.proxy;
//用作构建代理的接口
publicinterface ProxyInterface {
publicint sum(int a,int
b);
   
}
 

(2) 构建要代理的类A

package com.langsin.proxy;
 
publicclass
implements ProxyInterface{
    intvalue;
    public A() {
       //
TODO Auto-generated constructor stub
    }
 publicint sum(
int a,int b) {
    //
TODO Auto-generated method stub
     value=a+b;
    returnvalue;
}
 
}
(3)实现动态构建代理得类 CommonsProxy

package com.langsin.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
publicclass CommonsProxy 
implements InvocationHandler {
 
Object  realObj;
 
  //
构造函数赋值参数obj为要构建代理对象的类的对象
  public CommonsProxy(Object obj) {
    //
TODO Auto-generated constructor stub
this.realObj=obj;
}
 public Object getProxyObj(){
//Proxy.newProxyInstance(ClassLoader loader, Class[] interface,
、、、、//InvocationHandler h)
//要求loader必须能加在ProxyInterface,这里realObj的原对象实现了//ProxyInterface所以realObj自身的类加载器一定能
//加载ProxyInterface,h为实际执行函数调用的InvocationHandler实现对象。  
 
return  Proxy.newProxyInstance(realObj.getClass().getClassLoader(),
new Class[]{ProxyInterface.class},
this);
  }
 
 
 //实现自InvocationHandler的方法
 //实际代理类的方法执行通过调用此函数实现
 public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

    //
TODO Auto-generated method stub
     Object obj=method.invoke(this.realObj, args);
    return obj;
}
}

 

(4)进行测试: TestProxy类测试

package com.langsin.proxy;
 
publicclass TestProxy {
   
publicstaticvoid main(String[] args){
    A a=new A();
    CommonsProxy  proxy=new CommonsProxy(a);
    ProxyInterface  proxyIns=(ProxyInterface)proxy.getProxyObj();
    int result=proxyIns.sum(100, 200);
    System.out.println("代理类执行的结果为:"+result);
}
}

 

运行结果:

“代理类执行的结果为:300”

 

(二)要点注意:

 

以上例子中的

Proxy.newProxyInstance(realObj.getClass().getClassLoader(),
new Class[]{ProxyInterface.class},
this);

还可以代替为:

Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new
Class[]{ProxyInterface.class},
this);

或者代替为:

Proxy.newProxyInstance(realObj.getClass().getClassLoader(),realObj.getClass().getInterfaces,
this);

 

 

但此种方式不行:

(1)Class []  classes=new Class []{ProxyInterface.class };

 Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new
Cclasses ,
this);

或者

(2)Class [] 
classes= realObj.getClass().getInterfaces;

 Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),classes
, this);

 分析 Class
类是所有“对象.getClass()”的父类,本质上与子类对象体内容构造是有很大不同的,两者是不等价的。所以不能以此种方式代替!

 

 

(三)另一种复杂的构建方式

注:原类A与接口(CommonsProxy)原封不动
 
(1)实现动态构建代理得类 CommonsProxy
 
package com.langsin.proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
publicclass CommonsProxy 
implements InvocationHandler {
 
Object  realObj;
 
 //
构造函数赋值参数obj为要构建代理对象的类的对象
public CommonsProxy(Object obj) {
    //
TODO Auto-generated constructor stub
      this.realObj=obj;
}
 
 //实现自InvocationHandler的方法
 //实际代理类的方法执行通过调用此函数实现
 public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

    //
TODO Auto-generated method stub
Object obj=method.invoke(this.realObj, args);
return obj;
}
}

(2)在测试运行时直接生成代理类:TestProxy类测试

 

package com.langsin.proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
 
publicclass TestProxy {
   
publicstaticvoid main(String[] args) {
A a=new A();
 
//首先建建立执行代理的对象proxy
CommonsProxy  proxy=new CommonsProxy(a);
//直接建出接口的proxyClass
代理Class 
对象
// 利用Proxy.getProxyClass(ClassLoader loader,Class<?>... interfaces)
//创建
 
Class  proxyClass=Proxy.getProxyClass(ProxyInterface.class.getClassLoader(),new
Class[]{ ProxyInterface.class} ); 

ProxyInterface proxyIns;
try {
//通过反射构造函数Constructor类对象的newInstance(Object... initargs)方法
//(因Proxy有一个Proxy(InvocationHandler h)构造方法
//建出最终的代理类对象proxyIns
 
proxyIns = (ProxyInterface)proxyClass.
getConstructor(new Class[]{InvocationHandler.class})
.newInstance(proxy);
int result=proxyIns.sum(100, 200);
System.out.println("代理类执行的结果为:"+result);
} catch (IllegalArgumentException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
} catch (SecurityException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
} catch (InstantiationException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
} catch (IllegalAccessException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvocationTargetException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    //
TODO Auto-generated catch block
    e.printStackTrace();
}
             
}
}

运行结果:

代理类执行的结果为:300

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息