首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
AOP引入:OOP存在哪些局限性?
AOP常见使用场景
AOP概念:Aspect、Join Point和Advice等术语应该如何理解?
Java AOP设计模式:代理、判断和拦截器模式
Java AOP代理模式(Proxy):Java静态代理和动态代理的区别是什么?
Java AOP判断模式(Predicate):如何筛选Join Point?
Java AOP拦截器模式(Interceptor):拦截执行分别代表什么?
Spring AOP 功能概述:核心特性、编程模型和使用限制
Spring AOP编程模型:注解驱动、XML配置驱动和底层API
Spring AOP设计目标:Spring AOP与 AOP框架之间的关系是竞争还是互补?
Spring AOP Advice类型:Spring AOP丰富了哪些AOP Advice呢?
Spring AOP代理实现:为什么Spring Framework选择三种不同AOP实现?
JDK动态代理:为什么Proxy.newProxyInstance会生成新的字节码?
CGLIB动态代理:为什么Java动态代理无法满足AOP的需要?
AspectJ代理代理:为什么Spring推荐AspectJ注解?
AspectJ基础:Aspect、Join Points、Pointcuts和Advice语法和特性
AspectJ注解驱动:注解能完全替代AspectJ语言吗?
Spring核心基础:《小马哥讲Spring核心编程思想》还记得多少?
@AspectJ注解驱动
编程方式创建 @AspectJ代理
XML配置驱动 - 创建AOP代理
标准代理工厂API - ProxyFactory
@AspectJ Pointcut指令与表达式:为什么Spring只能有限支持?
XML配置Pointcut
API实现Pointcut
@AspectJ拦截动作:@Around与@Pointcut有区别吗?
XML配置Around Advice
API实现Around Advice
@AspectJ前置动作:@Before与@Around谁优先级执行?
XML配置Before Advice
API实现Before Advice
@AspectJ后置动作 - 三种After Advice之间的关系?
XML配置三种After Advice
API实现三种After Advice
自动动态代理
替换TargetSource
Spring AOP API整体设计
接入点接口 - Joinpoint
Joinpoint条件接口 - Pointcut
Pointcut操作 - ComposablePointcut
Pointcut便利实现
Pointcut AspectJ实现 - AspectJExpressionPointcut
Joinpoint执行动作接口 - Advice
Joinpoint Before Advice标准实现
Joinpoint Before Advice AspectJ实现
Joinpoint After Advice标准实现
Joinpoint After Advice AspectJ实现
Advice容器接口 - Advisor
Pointcut与Advice连接器 - PointcutAdvisor
Introduction与Advice连接器 - IntroductionAdvisor
Advisor的Interceptor适配器 - AdvisorAdapter
AdvisorAdapter实现
AOP代理接口 - AopProxy
AopProxy工厂接口与实现
JDK AopProxy实现 - JdkDynamicAopProxy
当前位置:
首页>>
技术小册>>
Spring AOP 编程思想(上)
小册名称:Spring AOP 编程思想(上)
### JDK动态代理:为什么`Proxy.newProxyInstance`会生成新的字节码? 在深入探讨`Proxy.newProxyInstance`方法如何生成新的字节码之前,我们首先需要理解Java动态代理(Dynamic Proxy)的基本概念、JDK动态代理的实现机制,以及这一机制背后的原理——特别是为什么需要生成新的字节码来支持代理逻辑的执行。 #### 一、Java动态代理简介 Java动态代理是Java反射机制的一个重要应用,它允许开发者在运行时动态地创建接口的代理实例,从而在不修改目标类代码的情况下,增加额外的行为(如日志记录、事务管理、安全检查等)。这种机制主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。 #### 二、JDK动态代理的实现机制 JDK动态代理主要通过`Proxy`类和`InvocationHandler`接口实现。`Proxy`类提供了创建动态代理实例的静态方法,而`InvocationHandler`接口则需要用户实现,以定义代理实例在调用方法时的行为。 1. **Proxy类**:该类提供了几个静态方法用于创建动态代理类和动态代理实例。其中,`newProxyInstance`方法最为核心,它接收三个参数:类加载器(`ClassLoader`)、要代理的接口列表(`Class<?>[] interfaces`)以及一个`InvocationHandler`实例。 2. **InvocationHandler接口**:该接口定义了一个`invoke`方法,该方法在代理实例的方法被调用时自动执行。通过这个方法,可以添加对原始方法调用的前后处理逻辑,或者完全改变方法调用的行为。 #### 三、为什么需要生成新的字节码? 在探讨为什么`Proxy.newProxyInstance`会生成新的字节码之前,我们需要先理解静态代理与动态代理的区别。静态代理通常通过定义一个代理类,该类实现与被代理对象相同的接口,并在内部持有被代理对象的引用。然而,这种方式需要为每一个被代理的接口编写一个代理类,不够灵活且维护成本高。 相比之下,动态代理则更加灵活,它能够在运行时动态地生成代理类。这种动态生成的能力正是通过生成新的字节码来实现的。具体而言,`Proxy.newProxyInstance`方法通过以下步骤生成新的字节码: 1. **分析接口**:首先,`Proxy`类会分析传入的接口列表,确定需要生成的代理类需要实现哪些接口。 2. **生成字节码**:接下来,`Proxy`类利用Java的字节码操作库(如ASM、Javassist等,尽管JDK内部实现可能直接操作字节码数组)动态生成代理类的字节码。这个代理类会实现所有传入的接口,并在每个方法内部调用`InvocationHandler`的`invoke`方法。这样,当代理实例的某个方法被调用时,实际上执行的是`InvocationHandler`中定义的逻辑。 3. **加载类**:生成的字节码会被传递给指定的类加载器(通常是调用者的类加载器)进行加载,从而创建出代理类的`Class`对象。 4. **创建实例**:最后,通过反射机制(如`Class.newInstance()`,注意在Java 9及以上版本已被弃用,应使用`Class.getDeclaredConstructor().newInstance()`等替代方式)创建出代理类的实例,并返回给调用者。 #### 四、生成新字节码的优势 动态代理通过生成新的字节码实现了高度的灵活性和可扩展性: - **无需手动编写代理类**:开发者无需为每一个接口或类编写代理类,极大地减少了代码量和维护成本。 - **运行时动态性**:代理行为可以在运行时动态改变,而无需重启应用程序或重新编译代码。 - **支持多接口代理**:JDK动态代理能够代理实现了多个接口的类,而静态代理通常只能针对单一接口进行代理。 #### 五、总结 `Proxy.newProxyInstance`方法通过生成新的字节码来创建动态代理实例,这一机制使得Java的动态代理功能变得非常强大和灵活。通过动态生成代理类的字节码,并在其中嵌入`InvocationHandler`的`invoke`方法调用,Java能够在不修改原有类代码的情况下,为对象添加新的行为或改变现有行为。这种机制在AOP(面向切面编程)、远程调用(RMI)、事务管理等场景中得到了广泛应用,极大地提升了Java应用程序的灵活性和可扩展性。 综上所述,虽然生成新的字节码在性能上可能会带来一定的开销(尤其是在代理类被大量创建和销毁时),但其带来的灵活性和便利性是无可替代的。因此,在需要动态代理的场景中,`Proxy.newProxyInstance`方法及其背后的动态字节码生成机制成为了Java开发者不可或缺的工具之一。
上一篇:
Spring AOP代理实现:为什么Spring Framework选择三种不同AOP实现?
下一篇:
CGLIB动态代理:为什么Java动态代理无法满足AOP的需要?
该分类下的相关小册推荐:
Java语言基础11-Java中的泛型
Java语言基础7-Java中的异常
Java语言基础13-类的加载和反射
Java语言基础14-枚举和注解
Mybatis合辑2-Mybatis映射文件
Java语言基础3-流程控制
Java语言基础4-数组详解
Java必知必会-Maven初级
Java语言基础15-单元测试和日志技术
Java语言基础1-基础知识
Mybatis合辑1-Mybatis基础入门
Mybatis合辑3-Mybatis动态SQL