jdk文档:
写道
动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。
测试代码如下:
一个接口:MyInterface
public interface MyInterface {
public void print();
public void test(int num);
}
实现以上接口的类:MyTest
public class MyTest implements MyInterface{
public void print(){
System.out.println("MyTest print");
}
public void test(int num){
System.out.println(num);
}
}
处理类:MyTestHandler
public class MyTestHandler implements InvocationHandler {
private MyInterface mytest = null;
public MyInterface bind(MyInterface test) { //注意传递的参数类型是接口,而不是实现类
this.mytest = test;
MyInterface proxyTest = (MyInterface) Proxy.newProxyInstance(test.getClass().getClassLoader(), test.getClass().getInterfaces(), this);
return proxyTest;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //具体的处理策略,根据方法名判断
Object obj = null;
if ("print".equals(method.getName())) {
System.out.println("got it");
} else if ("test".equals(method.getName())) {
int num = (Integer)args[0];
System.out.println(num+2);
} else {
obj = method.invoke(mytest, args); //交给目标对象处理
}
return obj;
}
}
测试类:Main
public class Main {
public static void main(String args[]){
MyTest test = new MyTest();
MyTestHandler handler = new MyTestHandler();
MyInterface proxy = handler.bind(test);//绑定方法返回对象的代理,以后可以操作该代理,隐藏了实际的对象
proxy.test(3);
}
}
分析:
通过对代理类的调用,代替了对实际类MyTest的调用,在invoke方法中,可以截获对方法的调用,针对特定的策略采取相应的措施。无需特殊处理的话,还是调用实际的对象的方法。
补充:
摘自jdk文档:
Proxy的静态方法:
写道
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces).
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces).
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });