JDK动态代理
JDK动态代理
JDK提供的动态代理。Java中提供了一个动态代理类Proxy,proxy提供了一个创建代理对象的静态方法(newProxyInstance方法)来获取代理对象
1> 卖票接口
/** * 卖票接口 * @author : lyn */ public interface SellTickets { /** * 卖票 */ void sell(); }
/** * 火车站 * @author : lyn */ public class TrainStation implements SellTickets { @Override public void sell() { System.out.println("火车站卖票!"); } }
3> 代理工厂
ProxyFactory不是代理模式中所说的代理类,代理类是程序在运行过程中动态的再内存中生成的类
public class ProxyFactory { private TrainStation trainStation = new TrainStation(); public SellTickets getProxyObject() { SellTickets proxyObject = (SellTickets) Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理点收取一定的费用!JDK动态代理的方式"); Object result = method.invoke(trainStation, args); return result; } }); return proxyObject; } }
新版本
import java.lang.reflect.Proxy; /** * 代理工厂 * @author : lyn */ public class ProxyFactory { private TrainStation trainStation = new TrainStation(); public SellTickets getProxyObject() { final String sell = "sell"; return (SellTickets) Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(), (proxy, method, args) -> { if (method.getName().equals(sell)) { System.out.println("代理点收取一定的费用,JDK动态代理方式"); } return method.invoke(trainStation, args); }); } }
/** * 测试类 * @author : lyn */ public class ProxyClient { public static void main(String[] args) { SellTickets proxyObject = new ProxyFactory().getProxyObject(); proxyObject.sell(); } }
ps:
newProxyInstance()方法参数说明
ClassLoader loader : 类加载器,用于加载代理类,使用真实对象的类加载器即可
Class<?>[] interfaces : 真实对象所实现的接口,代理模式真实对象和代理对象实现相同的接口
InvocationHandler h : 代理对象的调用处理程序
InvocationHandler中invoke方法参数说明:
proxy : 代理对象
method : 对应于在代理对象上调用的接口方法的 Method 实例
args : 代理对象调用接口方法时传递的实际参数
02 查看代理类结构
1> 截取的重要代码
//程序运行过程中动态生成的代理类 public final class $Proxy0 extends Proxy implements SellTickets { private static Method m3; public $Proxy0(InvocationHandler invocationHandler) { super(invocationHandler); } static { m3 = Class.forName("com.hjxr.test.jdkproxy.SellTickets").getMethod("sell", new Class[0]); } public final void sell() { this.h.invoke(this, m3, null); } } //Java提供的动态代理相关类 public class Proxy implements java.io.Serializable { protected InvocationHandler h; protected Proxy(InvocationHandler h) { this.h = h; } }
可以看出$Proxy0 代理类实现了SellTickets接口
2> 执行流程
测试类中通过代理对象调用sell()方法
根据多态的特性,执行的是代理类总的sell()方法
代理类中的sell()方法中又调用了InvocationHandler接口的子实现对象的invoke方法
invoke方法通过反射执行了真实对象所属类TrainStation的sell()方法