6.2、JDK动态代理

先看一下什么是静态代理: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)才是真正的代理类(得通过工具才能看到)

  1. 代理类($Proxy0)实现了SellTickets。这也就印证了我们之前说的真实类和代理类实现同样的接口。
  2. 代理类($Proxy0)将我们提供了的匿名内部类对象传递给了父类。

动态代理的执行流程是什么样?在这里插入图片描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值