代理是基本的设计模式之一,它是为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色。
而Java的动态代理比代理的思想更向前迈进了一步,它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。下面是用来展示动态代理的一个简单示例:
public interface Interface {
void doSomething();
void somethingElse(String arg);
}
public class RealObject implements Interface {
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething");
}
@Override
public void somethingElse(String arg) {
// TODO Auto-generated method stub
System.out.println("somethingElse " + arg);
}
}
public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
// TODO Auto-generated constructor stub
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args);
if(args != null){
for(Object arg : args){
System.out.println(arg);
}
}
return method.invoke(proxied, args);
}
}
public class DynamicProxyTest {
public static void consumer(Interface iface){
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("*******************未使用代理前*******************");
RealObject real = new RealObject();
consumer(real);
System.out.println("*******************使用代理后*******************");
InvocationHandler handler = new DynamicProxyHandler(real);
Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(), new Class[]{Interface.class}, handler);
consumer(proxy);
}
}
通过调用静态方法Proxy.newProxyInstance()可以创建动态代理,该方法有三个参数:
1、一个类加载器(classloader)。作为Java安全模型的一部分,对于系统类和从因特网上下载下来的类,可以使用不同的类加载器。
2、一个Class对象数组,每个元素都是需要实现的接口。
3、一个调用处理器,即InvocationHandler接口的一个实现。
动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递给一个“实际”对象的引用,从而使得调用处理器在执行其中介任务时,可以将请求转发。