【动态代理】JDK 动态代理的使用及原理

Java代理之jdk动态代理+应用场景实战 本文将先介绍jdk动态代理的基本用法,并对其原理和注意事项予以说明。之后将以两个最常见的应用场景为例,进行代码实操。这两个应用场景分别是和,它们在许多开发框架中广泛使用。比如在spring和mybatis中均使用了拦截器模式,在mybatis中还利用动态代理来实现声明性接口的功能。因此,掌握动态代理的原理和代码书写方式,对阅读理解这些开源框架非常有益。文中的示例代码基于jdk8编写,且都经过验证,但在将代码迁移到博客的过程中,难免存在遗漏。 阅读详情

在说动态代理之前,还是简单地回顾一下静态代理吧。

1. 静态代理

应用场景:

学生交作业给老师。现在想通过静态代理的方式,让班长(代理类)代替学生(被代理类)交作业给老师。

为了让代理类与被代理类有相同的行为,那么,通过会让被代理类去实现一个接口,而且,被代理类也会去实现相同的接口。如下:

静态代理案例

Person:公共接口

public interface Person {
	// 交作业的方法
    void handOut();
}

Student:被代理类

public class Student implements Person {

    @Override
    public void handOut() {
        System.out.println("学生交作业。");
    }
}

不使用静态代理

public class Test {

    public static void main(String[] args) {
        Person student = new Student();
        // 学生交作业。
        student.handOut();
    }

}

如果不使用静态代理,那么运行测试代码后,控制台将直接打印出:学生交作业。

使用静态代理

StudentProxy:代理类

public class StudentProxy implements Person {
	// 目标对象
    private Person person;

    public StudentProxy(Person person) {
        this.person = person;
    }

    @Override
    public void handOut() {
        System.out.println("【代理类】增强原方法");
        person.handOut();
    }

}

说明:

  1. 代理类中持有目标对象,然后通过构造器将目标对象传入;
  2. 重写 handOut() 方法,可增强被代理类的方法的功能。

修改测试类:

public class Test {

    public static void main(String[] args) {
        Person student = new Student();
        Person monitor = new StudentProxy(student);
        // 【代理类】增强原方法
		// 学生交作业。
        monitor.handOut();
    }

}

使用静态代理后,运行测试代码后,控制台将直接打印出:【代理类】增强原方法;学生交作业。

可见,StudentProxy#handOut() 方法确实增强了 Student#handOut() 方法
。

静态代理优、缺点

优点: 静态代理使用起来简单、方便
缺点: 一个代理类只能对一个业务接口的实现类进行包装,如果有多个业务接口的话就要定义很多实现类和代理类才行

2. JDK 动态代理

常用的动态代理有两类:JDK 动态代理、CGLIB 动态代理。这里主要讲下 JDK 动态代理。

2.1 JDK 动态代理介绍

JDK 动态代理是 JRE 提供给我们的类库,可以直接使用,不依赖第三方。

Java 动态代理类位于 java.lang.reflect 包下,一般主要涉及到以下两个类:

1. InvocationHandler:该接口中仅定义了一个方法:

public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
  • proxy:动态代理对象
  • method:被代理的方法
  • args:方法的参数数组

这个抽象方法在代理类中动态实现

2. Proxy:该类即为动态代理类

Proxy#newProxyInstance():返回代理类的一个实例

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException

动态代理类:它是在运行时生成的一种类,在生成它时,必须提供一组 interfaces 给它,然后该类就会实现这些 interface。动态代理类就是 Proxy,它不会替你干任何事,在生成它的时候,也必须提供一个 handler,由它接管实际的工作。

2.2 JDK 动态代理使用

JDK 动态代理使用步骤

动态代理步骤:

  1. 创建一个实现了接口 InvocationHandler 的类,它必须实现 invoke() 方法
  2. 创建被代理的类和公共接口
  3. 调用 Proxy.newProxyInstance() 方法创建一个代理类
  4. 通过代理对象调用方法

我们使用 JDK 动态代理来实现下上面的应用场景吧。

Person:公共接口

public interface Person {
	// 交作业的方法
    void handOut();
}

Student:被代理类

public class Student implements Person {

    @Override
    public void handOut() {
        System.out.println("学生交作业。");
    }
}

InvocationHandler 实现类

添加一个 InvocationHandler,它不是代理类,因为它并没有实现公共接口 Person,它仅仅是一个包装器 wrapper。包装了 target 对象。

public class PersonHandlerImpl<T> implements InvocationHandler {

    // 被代理对象
    private T target;

    public PersonHandlerImpl(T target) {
        this.target = target;
    }

    /**
     * @param proxy: 动态代理对象
     * @param method: 正在执行的方法
     * @param args: 调用目标方法时传入的实参
     **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("【增强方法】代理对象正在执行的方法:" + method.getName());
        Object result = method.invoke(target, args);
        return result;
    }

}

添加一个代理工厂类 ProxyFactory:生产代理对象

public class ProxyFactory {

    public static Object creatProxyObj(Object target) {
        PersonHandlerImpl handler = new PersonHandlerImpl(target);
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
    }

}

测试类:

public class Test {

    public static void main(String[] args) {
        Person student = new Student();
        Person studentProxy = (Person) ProxyFactory.creatProxyObj(student);
        studentProxy.handOut();
    }

}

Proxy 根据 target 的接口生成了一个实现类,它就是动态代理类 $Proxy0。

生成过程:由于拿到的是接口,那么,我们便可以获知接口的所有的信息(方法的定义),也就能声明一个类去实现这个接口,并重写这个接口中所有的方法。而在这些重写的方法中会调用其它对象的方法。当然,这个被调用的对象不能是 target。因为,如果是 target 对象,那么,我们如何增强其中的方法 handOut()。

所以,它调用的是 target 的包装类,这个类需要我们来实现。但是,JDK 给出了约束,这个包装类要实现 InvocationHandler 接口。上述例子中,就是 PersonHandlerImpl。这个类里面有个方法,它是 target 的所有方法的调用入口 invoke()。在调用它之前,我们可以加自己的代码增强。

所以,可以这么认为:动态代理类 代理了 InvocationHandler,而 InvocationHandler 又代理了我们的 target,两级代理

2.3 JDK 动态代理的原理

通过 Debug 模式,我们可以知道:当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的 handler 对象的 invoke() 方法来进行调用。

即:当调用 studentProxy.handOut() 方法时,

Person studentProxy = (Person) ProxyFactory.creatProxyObj(student);
studentProxy.handOut();

会自动调用 PersonHandlerImpl#invoke() 方法:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("【增强方法】代理对象正在执行的方法:" + method.getName());
    Object result = method.invoke(target, args);
    return result;
}

这是为什么呢???

过程分析:

我们通过 Debug 模式看代码慢慢分析:

首先看看 Proxy#newProxyInstance() 方法:返回一个代理类对象

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
	// 1.校验 InvocationHandler 是否为空
    Objects.requireNonNull(h);

    // 2.根据类加载器和接口来获取动态代理类对应的 Class 类型
    Class<?> cl = getProxyClass0(loader, intfs);

	// 3.通过反射来获取构造器对象并生成动态代理对象
    try { 
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        //...
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    }
    // ...
}

重点看第2步:Proxy#getProxyClass0 方法:

// 代理类缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
// ...

private static Class<?> getProxyClass0(ClassLoader loader,
                                       Class<?>... interfaces) {
    // 1.公共接口数量不能超过 2^16 - 1 个
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    // 2.先从缓存中取代理类实例。如果缓存中有,则直接去;否则,需要ProxyClassFactory生成代理类
    return proxyClassCache.get(loader, interfaces);
}

查看 WeakCache#get() 方法:

public V get(K key, P parameter) {
    //...

    while (true) {
        if (supplier != null) {
            V value = supplier.get();
            if (value != null) {
                return value;
            }
        }
    }
    //...
}

虽然,这个 get() 方法有很多逻辑,但是,它最后一定会调用 V value = supplier.get(); 并且,会返回 value。因为,这是一个 while(true) 循环,且只有一个 return 语句。

查看 Factory#get() 方法:

Factory 为 WeakCache 的一个内部类

public synchronized V get() { // serialize access
        //...
        
        V value = null;
        try {
            value = Objects.requireNonNull(valueFactory.apply(key, parameter));
        } finally {
            if (value == null) { // remove us on failure
                valuesMap.remove(subKey, this);
            }
        }
      	//...
      	
        return value;
    }
}

查看 valueFactory.apply(key, parameter) 语句。其中,valueFactory 是一个代理工厂 Proxy$ProxyClassFactory。

Proxy$ProxyClassFactory#apply() 方法:

public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
        //...

        if (proxyPkg == null) {
            proxyPkg = com.sun.proxy + ".";
        }

        // 代理对象的名称
        long num = nextUniqueNumber.getAndIncrement();
        String proxyName = proxyPkg + "$Proxy" + num;

        // 1.生成代理对象字节码
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
            proxyName, interfaces, accessFlags);
        try {
            return defineClass0(loader, proxyName,
                                proxyClassFile, 0, proxyClassFile.length);
        } 
        //...
    }
}

通过这个方法,我们来生成一个字节码文件看看:

public class Test2 {

    public static void main(String[] args) {
        Person student = new Student();
        Person studentProxy = (Person) ProxyFactory.creatProxyObj(student);
        studentProxy.handOut();
        // 生成字节码文件
        createProxyClassFile();
    }

    private static void createProxyClassFile(){
        String name = "ProxyObject";
        byte[] data = ProxyGenerator.generateProxyClass(name, new Class[]{Person.class});
        FileOutputStream out =null;
        try {
            out = new FileOutputStream(name + ".class");
            out.write(data);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

反编译这个 class 文件:

public final class ProxyObject extends Proxy implements Person {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public ProxyObject(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void handOut() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.zzc.proxy.dynamicproxy.Person").getMethod("handOut");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

这就是我们生成的真正的动态代理类:$Proxy0。

它继承了 Proxy 类,并且实现了公共的接口 Person。

语句:Person studentProxy = (Person) ProxyFactory.creatProxyObj(student); 中的
studentProxy 就是它的一个实例。

语句:studentProxy.handOut(); 就是调用动态代理类中的方法:

public final void handOut() throws  {
    try {
        super.h.invoke(this, m3, (Object[])null);
    }
    //...
}

所以,为什么会自动调用 PersonHandlerImpl#invoke() 方法?

因为 JDK 生成了一个动态代理类,它继承 Proxy,并实现了 Person 接口,自然会重写 handOut() 方法。在重新的方法中,又通过反射去调用了 PersonHandlerImpl#invoke() 方法。

C语言练习题:据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。已知市斤的数值是公斤数值的两倍。现给定某人身高,请你计算其标准体重应该是多少? 题目内容: 据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。已知市斤的数值是公斤数值的两倍。现给定某人身高,请你计算其标准体重应该是多少?(顺便也悄悄给自己算一下吧……) 输入格式: 输入第一行给出一个正整数H(100 < H ≤ 300),为某人身高。 输出格式: 在一行中输出对应的标准体重,单位为市斤,保留小数点后1位。 输入样例: 169 输出样例: 124.2 代码如下: #include<stdio.h> int main() { i 阅读详情

相关推荐

Carla学习笔记(一)服务器跑carla本地显示窗口

其中host后替换为你的服务器IP,-carla-rpc-port和-p后为端口号,需要一致。python3 manual_control.py也可以替换为其他python脚本。因为电脑配置不够,所以在服务器跑carla,本地运行PythonAPI里的样例。把carla仓库的PythonAPI拷贝到本地,或者直接去官方里下载一下。

做题记录 4969

jdk动态代理使用详解

jdk动态代理和cglib静态代理使用详解

congge 2万+

python入门:Anaconda和Jupyter notebook的安装与使用

一、安装和使用Anaconda 1、anaconda是什么? Anaconda在英文中是“巨蟒”的意思,与python的意思相近,它是python的包管理器和环境管理器。 2、为什么需要安装anaconda? 原因有以下几点: 附带一大批常用的数据科学包,方便立即开始处理数据 管理包 anaconda是在conda(一个包管理器和环境管理器)上发展来的;而conda可以很方便地对第三方的包进行安装、卸载和更新。 管理环境 conda可以为不同的项目建立不同的运行环境,避免不同的项目或包版本

PY洋洋 1万+

【Java基础】细说java动态代理及使用场景

Java代理模式是一种结构型设计模式,它允许通过创建一个代理对象来间接访问另一个对象,从而控制对原始对象的访问。

fumeidonga的博客 3107

MATLAB双目相机标定:从工具箱实战到参数精解

本文详细讲解了使用MATLAB进行双目相机标定的完整实战流程与参数精解。从拍摄合格的棋盘格图像、设置关键参数(如径向畸变系数),到分析重投影误差、优化结果并正确导出和使用内外参,提供了从操作到原理的全面指导,帮助读者为立体视觉应用奠定精准基础。

weixin_29041767的博客 255

材料带隙预测(图神经网络)(⭐⭐)—— 用晶体图网络预测钙钛矿材料的能带隙,加速光伏材料筛选。技术栈:CGCNN、MEGNet、Materials Project数据集

钙钛矿太阳能电池以其高效率、低成本的优势迅速崛起,但传统“试错法”材料筛选效率极低,严重制约了光伏技术的迭代速度。近年来,基于图神经网络的材料带隙预测方法,特别是晶体图神经网络(CGCNN)和材料图网络(MEGNet),为这一问题提供了革命性的解决方案。本文系统梳理了材料带隙预测从传统计算到深度学习的演进历程,深入剖析了CGCNN与MEGNet的架构设计、数学原理及创新机制,详细阐述了Materials Project数据集的构建、特征工程与处理策略。

2201_76125393的博客 39

一文搞懂Java动态代理的用法和使用场景

Java的动态代理,在日常开发中可能并不经常使用,但是并不代表他不重要。Java的动态代理的最主要的用途就是应用在各种框架中。因为使用动态代理可以很方便的运行期生成代理类,通过代理类可以做很多事情,比如AOP,比如过滤器、拦截器等。

oandy0的博客 1528

【深度学习|多实例学习】多实例学习(Multiple Instance Learning, MIL)的起源、发展和应用,附代码(一)

【深度学习|多实例学习】多实例学习(Multiple Instance Learning, MIL)的起源、发展和应用,附代码(一)

2401_89898861的博客 1911

JAVA动态代理

java中有两种常见的动态代理方式 JDK原生动态代理和CGLIB动态代理使用以及原理

qq_32117059的博客 1784

【零基础学习CAPL】——CAN报文的发送(CRC——ChecSum值)

本章主要介绍带有CRC值的报文发送一般报文可使用CANoe的IG模块直接发送,但带有CRC值的报文就只能编写脚本进行发送,以下详细讲解在配合Panel面板情况下,如何进行带有循环冗余码的报文进行报文的发送。

LOVE135149的博客 1905

基于SOLIDWORKS API的工业级插件开发指南

SOLIDWORKS API是基于COM技术的一套开发接口,支持C#、VB.NET等语言,用于自动化建模、属性管理、界面定制等功能。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 2728

Java JDK 动态代理(AOP)使用及实现原理分析

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息 ​ 一、什么是代理? 二、Java 动态代理类 三、JDK的动态代理怎么使用? 四、动态代理怎么实现的? 五、结论 一、什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。 代理模式UML图: 简单结构示意图: 为了保持行为的...

勿忘初心 16万+

把审批体验做成一体化:SAP Business Workflow 里的 Secondary Method、Before Method 与 After Method

摘要:SAP Business Workflow 中,Task 的 Secondary、Before 和 After 三类方法对提升审批体验和可追溯性至关重要。Secondary Method 可自动展示辅助信息(如审批时弹出排班报表),但需注意其独立会话特性;Before Method 适合预处理和审计留痕;After Method 确保收尾动作可靠执行。三类方法按特定顺序调用,且错误不影响主流程。合理使用这些方法能减少事务码切换,增强审计能力,优化用户体验。(149字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 179

JDK动态代理-使用及原理

JDK动态代理 为了引出动态代理,我们看看一个案列! 广东广州,早上9:00,一位靓仔穿着人字拖、提着鸟笼,走进了早茶店。没错,这就是广州典型的包租公!名下几栋楼,只收租为生,没工作,这人身真是无趣至极! 这里就得出一个问题:收租不算工作?好吧,其实正真的包租公不会自己去收租,都是委托给中介去做。为什么呢?这其中可以说牵扯到安全、隐私等等。想一下,假如包租公自己收租,当下租客很多,其他包租公就不爽了,干脆找人去捣乱,比如只问不租,浪费包租公时间。当然不仅仅是这样… 简单使用 好的,租房中介就出来了,租客看

Coding~Farmer 865

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

JDK 动态代理使用以及实现原理

一、什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。 代理模式UML图: 简单结构示意图: 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以...

milaier的专栏 148

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Java】JDK CGLib 动态代理 使用、原理分析

只能针对接口进行代理一个实现了接口的实例。代理对象的方法调用会被转发到这个的invoke方法,由它处理具体的逻辑。

奶酪的博客 487

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Java JDK 动态代理使用及实现原理分析

http://blog.csdn.net/jiankunking/article/details/52143504 版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 一、什么是代理? 代理是一种常

tianjinsong的专栏 4991

JDK动态代理使用及原理解析

JDK动态代理使用及原理解析 一、动态代理的使用   1.1 动态代理简单示例   1.2 创建代理实例在代理类中   1.3 公用的代理类 二、如何进入到代理类中的invoke的?   2.1 拿到$Proxy0这个类   2.2 $Proxy0的解析 三、Proxy.newProxyInstance是如何生成一个代理对象然后返回的? 一、动态代理的使用 1.1 动态代理简单示例      动态代理类图如下:      主体和实际主体代码如下所示: /** * 主体 */ public in

301

深入理解JDK动态代理原理,使用javassist动手写一个动态代理框架

vm options参数设置-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true,就可以把生成的代理类的源码保存在com.sun.proxy目录下面,或者用arthas来查看运行中的类信息。

秃了也弱了 1136

JDK动态代理-使用及原理全面讲解,还不明白的看这一篇就够了

JDK动态代理 为了引出动态代理,我们看看一个案列! 广东广州,早上9:00,一位靓仔穿着人字拖、提着鸟笼,走进了早茶店。没错,这就是广州典型的包租公!名下几栋楼,只收租为生,没工作,这人身真是无趣至极! 这里就得出一个问题:收租不算工作?好吧,其实正真的包租公不会自己去收租,都是委托给中介去做。为什么呢?这其中可以说牵扯到安全、隐私等等。想一下,假如包租公自己收租,当下租客很多,其他包租公就不爽了,干脆找人去捣乱,比如只问不租,浪费包租公时间。当然不仅仅是这样… 简单使用 好的,租房中介就出来了,租客看房

weixin_53170684的博客 381

Java-JDK动态代理(AOP)使用及实现原理分析

Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我们在用Spirng和Mybatis的时候,要理解怎么使用的. 1.什么是代理? 代理,在我们日常生活之中就有体现,代购,中介,换ip,商家等等. 比如有一家美国的大学,可以对全世界招生.留学中介(代理 ) 留学中介(代理):帮助这家美国的学校招生,中介是学校的代理中介是代替学校完成招生功能 代理特点 中介

以码平川的博客 619

Spring原理学习(五):一篇讲清楚动态代理(jdk和cglib)的使用、原理和源码

在下面的模拟中,我们的代理目标是Target类,他实现了Foo接口。在main方法中,我们模拟jdk实现动态代理的方法,来模拟实现AOP代理增强。需要注意的一点是:jdk只能针对接口代理。运行结果:需要注意:代理对象Proxy 和 代理目标Target是兄弟关系,他们都实现了Foo接口。所以,目标类Target也可以是final类型,这点与cglib实现的动态代理不同。

m0_49499183的博客 2689

JDK动态代理使用及底层原理和源码

JDK动态代理步骤 1.实现代理前需要实现一个接口的invoke方法即可 2. 使用动态代理如下关键代码 3.执行结果 调试JDK动态代理源码 首先进入newProxyInstance方法,719行代码是获取到代理对象的Class com.sun.proxy包下的,而且类名有个0结尾,避免代理类重复,保持唯一ID 紧接着跟进去719行代码的细节 Class<?> cl = getProxyClass0(loader, intfs); 429行代码很关键,首先从缓存中找接口, 找不到

不骄不傲的博客 992

AOP之JDK 动态代理使用及实现原理分析

JDK动态代理代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

代码整洁之道 311
上一篇: 【Log】(三)Java 中的日志框架 logback、log4j2
下一篇: 【动态代理】CGLIB 动态代理的使用及原理
sco5282
博客等级 码龄5年 844粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值