本文共 3301 字,大约阅读时间需要 11 分钟。
代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问。由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
静态代理的特点是代理类在编译期就生成。常见的例子是火车站卖票的场景。顾客通过代售点购买火车票,实际上仍然是火车站卖票。类图如下:
+------------+| 代售点 |+------------+| || 卖票方法 || |+------------+
实例说明:
public interface SellTickets { void sell();}public class TrainStation implements SellTickets { public void sell() { System.out.println("火车站卖票"); }}public class ProxyPoint implements SellTickets { private TrainStation station = new TrainStation(); public void sell() { System.out.println("代理点收取一些服务费用..."); station.sell(); }}public class Client { public static void main(String[] args) { ProxyPoint proxyPoint = new ProxyPoint(); proxyPoint.sell(); }} 动态代理的特点是代理类在运行时动态生成。Java提供了一个代理类Proxy(JDK1.3提供),用于创建代理对象。Proxy.newProxyInstance方法用于获取代理对象:
public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h) { return Proxy.newProxyInstance(loader, interfaces, h);} InvocationHandler接口的invoke方法参数说明:
proxy:代理对象method:对应于在代理对象上调用的接口方法的Method实例args:代理对象调用接口方法时传递的实际参数实例说明:
public class ProxyFactory { private TrainStation station = new TrainStation(); public SellTickets getProxyObject() { SellTickets sellTickets = (SellTickets) Proxy.newProxyInstance( station.getClass().getClassLoader(), station.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("(jdk动态代理)代售点收取了一定的手续费用..."); Object result = method.invoke(station, args); return result; } } ); return sellTickets; }}public class Client { public static void main(String[] args) { ProxyFactory factory = new ProxyFactory(); SellTickets proxyObject = factory.getProxyObject(); proxyObject.sell(); }} CGLib是第三方开源库,用于动态代理。它通过生成字节码实现动态代理的效果。在没有接口的情况下,CGLib更适合实现动态代理。它的优点是速度快,但缺点是只能代理非final类。
实例说明:
public class TrainStation { public void sell() { System.out.println("火车站卖票"); }}public class ProxyFactory implements MethodInterceptor { private TrainStation station = new TrainStation(); public TrainStation getProxyObject() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(station.getClass()); enhancer.setCallback(this); TrainStation obj = (TrainStation) enhancer.create(); return obj; } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("代理点收取一些服务费用(CGLib动态代理方式)..."); return methodProxy.invokeSuper(o, objects); }}public class Client { public static void main(String[] args) { ProxyFactory proxyFactory = new ProxyFactory(); TrainStation proxyObject = proxyFactory.getProxyObject(); proxyObject.sell(); }} 两者的区别主要在于目的和获取方式:
MapperProxyFactory实现动态代理。转载地址:http://yhzg.baihongyu.com/