先看一下什么是静态代理:https://blog.youkuaiyun.com/GLOAL_COOK/article/details/117065944
接下来我们使用动态代理实现上面案例,先说说JDK提供的动态代理。Java中提供了一个动态代理类Proxy,Proxy并不是我们上述所说的代理对象的类,而是提供了一个创建代理对象的静态方法(newProxyInstance方法)来获取代理对象。
//售票接口
public interface SellTickets {
void sell();
}
//目标对象 火车站
public class TrainStation implements SellTickets {
@Override
public void sell() {
System.out.println("火车站售票了");
}
}
//代理工厂,用来创建代理对象 这里并不是代理类
public class ProxyFactory {
//也是使用聚合
private TrainStation station=new TrainStation();
//自定义
public SellTickets getProxyObject(){
//使用Proxy获取代理对象
SellTickets sellTickets = (SellTickets)Proxy.newProxyInstance(
//1、ClassLoader loader : 类加载器,用于加载代理类,使用真实对象的类加载器即可
station.getClass().getClassLoader(),
//2、Class<?>[] interfaces : 真实对象所实现的接口(也是代理对象要写的),
// 代理模式真实对象和代 理对象实现相同的接口
station.getClass().getInterfaces(),
//3、InvocationHandler h : 代理对象的调用处理程序
/* InvocationHandler中invoke方法参数说明:
proxy : 代理对象
method : 对应于在代理对象上调用的接口方法的Method 实 例
args : 代理对象调用接口方法时传递的实际参数
*/
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这里可以写增强方法
System.out.println("代理店收取额外费用");
//执行真实对象的方法,是哪个目标对象就写哪个,args是形参,就是调用方法如果有参就传来这里的
//这里返回obj是调用方法的返回值,void 就返回null,invoke是用了反射
Object obj = method.invoke(station, args);
return obj;
}
}
);
return sellTickets;
}
}
//test
public class Client {
public static void main(String[] args) {
//获取代理对象
//1,创建代理工厂对象
ProxyFactory proxyFactory = new ProxyFactory();
//2,使用factory对象的方法获取代理对象
SellTickets proxyObject = proxyFactory.getProxyObject();
//3,其实是调用代理类的sell方法,其实就是调用了invoke方法
proxyObject.sell();
}
}
底层原理:
使用了动态代理,我们思考下面问题:
ProxyFactory是代理类吗?
ProxyFactory不是静态代理中所说的代理类,而代理类是程序在运行过程中动态的在内存中生(得通过下面工具获得)成的类。通过阿里巴巴开源的 Java 诊断工具(Arthas【阿尔萨斯】)查看代理类的结构:

从上面的类中,我们可以看到以下几个信息,($Proxy0)才是真正的代理类(得通过工具才能看到):
- 代理类($Proxy0)实现了SellTickets。这也就印证了我们之前说的真实类和代理类实现同样的接口。
- 代理类($Proxy0)将我们提供了的匿名内部类对象传递给了父类。
动态代理的执行流程是什么样?
416





