在Java中利用代理(Proxy)可以在运行时创建一个实现了一组给定接口的新类。
在系统程序设计中,有时需要面对无法确定接口,却需要构造对象的情况。以前为了解决此问题,有些程序根据动态确定的接口,生成Java类文件,然后调用类加载器构造该对象,然后使用,这样一来无可避免性能问题。通过代理类,能够在不额外创建Java文件的情况下构造对象及调用该对象方法。
使用代理的理由有很多,其中就有如下的情况:
1.路由对远程服务器的方法调用
2.在程序运行期间,将用户接口事件与行动关联起来
3.调试时跟踪方法调用
以下举出一例,使用代理和调用处理器跟踪方法调用
HelloWorld.class接口
HellWorld实现类
测试类
在系统程序设计中,有时需要面对无法确定接口,却需要构造对象的情况。以前为了解决此问题,有些程序根据动态确定的接口,生成Java类文件,然后调用类加载器构造该对象,然后使用,这样一来无可避免性能问题。通过代理类,能够在不额外创建Java文件的情况下构造对象及调用该对象方法。
使用代理的理由有很多,其中就有如下的情况:
1.路由对远程服务器的方法调用
2.在程序运行期间,将用户接口事件与行动关联起来
3.调试时跟踪方法调用
以下举出一例,使用代理和调用处理器跟踪方法调用
HelloWorld.class接口
public interface HelloWorld {
public void SayHello(String name);
}
HellWorld实现类
public class HelloWorldImpl implements HelloWorld {
public void SayHello(String name) {
System.out.println("Hello,"+name);
}
}
测试类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。
//该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类
public class ProxyTest {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorldImpl();
DynamicProxy dp = new DynamicProxy();
//在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。
HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);
helloWorld1.SayHello("cookies");
System.out.println(Proxy.isProxyClass(helloWorld1.getClass()));
//helloWorld2将不被拦截
HelloWorld helloWorld2 = new HelloWorldImpl();
helloWorld2.SayHello("cookies");
}
}
class DynamicProxy implements InvocationHandler
{
private Object object;
//绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。
//Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法
public Object bindRelation(Object object){
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);
}
//拦截关联的这个实现类的方法被调用时将被执行
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Welcome");
Object result = method.invoke(object, args);
return result;
}
}