从源码角度讲述动态代理的实现

本文从源码角度详细介绍了Java动态代理的实现,包括静态代理、JDK动态代理(接口代理)和Cglib动态代理。通过实例代码和源码分析,解释了动态代理的生成过程和工作原理,帮助读者理解代理模式的优缺点及其应用场景。
摘要由CSDN通过智能技术生成

一、引言

Spring 中,最重要的应该当属 IOCAOP 了,IOC 的源码流程还比较简单,但 AOP 的流程就较为抽象了。

其中,AOP 中代理模式的重要性不言而喻,但对于没了解过代理模式的人来说,痛苦至极

于是,我就去看了动态代理的实现,发现网上大多数文章讲的都是不清不楚,甚至讲了和没讲似的,让我极其难受

本着咱们方向主打的就是源码,直接从从源码角度讲述一下 代理模式

兄弟们系好安全带,准备发车!

注意:本文篇幅较长,请留出较长时间来阅读

二、定义

代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

举个生活中常见的例子:客户想买房,房东有很多房,提供卖房服务,但房东不会带客户看房,于是客户通过中介买房。

这时候对于房东来说,不直接和客户沟通,而是交于中介进行代理

对于中介来说,她也会在原有的基础上收取一定的中介费

三、静态代理

我们创建 Landlord 接口如下:

public interface Landlord {
    // 出租房子
    void apartmentToRent();
}
复制代码

创建其实现类 HangZhouLandlord 代表杭州房东出租房子

public class HangZhouLandlord implements Landlord {
    @Override
    public void apartmentToRent() {
        System.out.println("杭州房东出租房子");
    }
}
复制代码

创建代理类 LandlordProxy,代表中介服务

public class LandlordProxy {

    public Landlord landlord;

    public LandlordProxy(Landlord landlord) {
        this.landlord = landlord;
    }

    public void apartmentToRent() {
        apartmentToRentBefore();
        landlord.apartmentToRent();
        apartmentToRentAfter();
    }

    public void apartmentToRentBefore() {
        System.out.println("出租房前,收取中介费");
    }

    public void apartmentToRentAfter() {
        System.out.println("出租房后,签订合同");
    }
}
复制代码

创建最终测试:

public class JavaMain {
    public static void main(String[] args) {
        Landlord landlord = new HangZhouLandlord();

        LandlordProxy proxy = new LandlordProxy(landlord);
		  // 从中介进行租房
        proxy.apartmentToRent();
    }
}
复制代码

得出最终结果:

出租房前,收取中介费
杭州房东出租房子
出租房后,签订合同
复制代码

通过上述 demo 我们大概了解代理模式是怎么一回事

  • 优点:
    • 在不修改目标对象的功能前提下,能通过代理对象对目标功能扩展
  • 缺点:
    • 代理对象需要与目标对象实现一样的接口,所以会有很多代理类,一旦接口增加方法,目标对象与代理对象都要维护

四、动态代理

动态代理利用了JDK API,动态地在内存中构建代理对象,从而实现对目标对象的代理功能,动态代理又被称为JDK代理或接口代理。

静态代理与动态代理的区别:

  • 静态代理在编译时就已经实现了,编译完成后代理类是一个实际的 class 文件
  • 动态代理是在运行时动态生成的,即编译完成后没有实际的 class 文件,而是在运行时动态生成类字节码,并加载到 JVM

1、JDK代理

代码如下:

public class ProxyFactory {
    // 目标方法
    public Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                // 目标对象的类加载器
                target.getClass().getClassLoader(),
                // 目标对象的接口类型
                target.getClass().getInterfaces(),
                // 事件处理器
                new InvocationHandler() {
                    /**
                     *
                     * @param proxy  代理对象
                     * @param method 代理对象调用的方法
                     * @param args   代理对象调用方法时实际的参数
                     * @return
                     * @throws T
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值