11.6 动态代理
Java 的反射 API 还有最后一个功能没讲——创建动态代理。动态代理是实现了一些接口的类(扩展 java.lang.reflect.Proxy 类)。这些类在运行时动态创建,而且会把所有调用都转交给 InvocationHandler 对象处理:
InvocationHandler h = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {String name = method.getName();System.out.println("Called as: "+ name);switch (name) {case "isOpen":return false;case "close":return null;}return null;}};Channel c =(Channel) Proxy.newProxyInstance(Channel.class.getClassLoader(),new Class[] { Channel.class }, h);c.isOpen();c.close();
代理可以用作测试的替身对象(尤其是测试使用模拟方式实现的对象)。
代理的另一个作用是提供接口的部分实现,或者修饰或控制委托对象的某些方面:
public class RememberingList implements InvocationHandler {private final List<String> proxied = new ArrayList<>();@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {String name = method.getName();switch (name) {case "clear":return null;case "remove":case "removeAll":return false;}return method.invoke(proxied, args);}}RememberingList hList = new RememberingList();List<String> l =(List<String>) Proxy.newProxyInstance(List.class.getClassLoader(),new Class[] { List.class },hList);l.add("cat");l.add("bunny");l.clear();System.out.println(l);
代理的功能特别强大而且灵活,很多 Java 框架都有使用。
