首页
技术小册
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 编程思想(上)
### 章节:自动动态代理 在深入探讨Spring AOP(面向切面编程)的精髓之前,理解自动动态代理机制是不可或缺的一环。Spring AOP通过动态代理技术,在不修改源代码的情况下,为对象的行为增加额外的功能(如日志、事务管理等),从而实现了横切关注点(cross-cutting concerns)的模块化。本章将详细解析Spring中自动动态代理的实现原理、应用场景、配置方式以及背后的技术细节。 #### 一、动态代理简介 动态代理是一种设计模式,它能够在运行时动态地创建接口的代理实例。这种代理可以拦截对目标对象的方法调用,并在调用前后执行特定的操作,如权限检查、日志记录等。Java提供了两种主要的动态代理实现方式:基于接口的JDK动态代理和基于类的CGLIB动态代理。 - **JDK动态代理**:利用`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。它要求目标对象必须实现一个或多个接口,因为代理类是基于这些接口创建的。 - **CGLIB动态代理**:通过操作字节码来生成代理类,因此不需要目标对象实现接口。CGLIB代理是通过继承目标类来工作的,因此它适用于没有实现接口的类。 #### 二、Spring AOP中的自动动态代理 Spring AOP默认使用JDK动态代理或CGLIB代理来创建代理对象,具体使用哪一种取决于目标对象的特性。如果目标对象实现了至少一个接口,则Spring AOP默认使用JDK动态代理;如果目标对象没有实现任何接口,则使用CGLIB代理。 ##### 2.1 自动选择代理策略 Spring框架通过`AopProxyFactory`类来决定使用哪种代理策略。这个决策过程大致如下: 1. **检查目标对象是否实现了接口**:如果实现了接口,则倾向于使用JDK动态代理,因为这种方式性能更好且代码更简洁(不依赖于第三方库)。 2. **如果没有实现接口**:则使用CGLIB代理。CGLIB通过生成目标类的子类来创建代理,因此能够代理没有实现接口的类。 ##### 2.2 代理的创建过程 无论是JDK动态代理还是CGLIB代理,Spring AOP在创建代理对象时都遵循相似的步骤: 1. **确定目标对象和增强器(Advice)**:目标对象是需要被增强的对象,而增强器则定义了要增加的行为。 2. **创建代理配置**:根据目标对象和增强器的信息,配置代理的行为,包括要拦截的方法、增强器的执行顺序等。 3. **生成代理类**:根据代理配置,动态生成代理类的字节码(对于CGLIB)或代理实例(对于JDK动态代理)。 4. **实例化代理对象**:将目标对象和增强器传递给代理类的构造函数(对于CGLIB)或`InvocationHandler`(对于JDK动态代理),以创建代理对象的实例。 5. **返回代理对象**:将创建好的代理对象返回给客户端,客户端通过代理对象与目标对象交互,而不知道代理对象的存在。 #### 三、自动动态代理的应用场景 自动动态代理在Spring AOP中扮演着至关重要的角色,它使得横切关注点(如日志、事务管理、安全控制等)的模块化实现成为可能。以下是一些典型的应用场景: 1. **日志记录**:在不修改业务逻辑代码的情况下,为方法调用添加日志记录功能,帮助开发者追踪系统行为。 2. **事务管理**:自动为数据库操作提供事务支持,确保数据的一致性和完整性。 3. **安全控制**:在方法执行前进行权限检查,防止未授权访问。 4. **性能监控**:记录方法调用的时间和资源消耗,帮助开发者优化系统性能。 5. **缓存管理**:根据方法的输入和输出自动缓存结果,减少不必要的计算和数据库访问。 #### 四、配置自动动态代理 在Spring框架中,配置自动动态代理通常是通过XML配置文件或注解来完成的。 ##### 4.1 XML配置 在Spring的XML配置文件中,可以通过`<aop:config>`标签来启用AOP支持,并通过`<aop:advisor>`或`<aop:aspect>`标签来定义增强器和切点。例如: ```xml <aop:config> <aop:aspect id="myAspect" ref="myAspectBean"> <aop:pointcut id="myPointcut" expression="execution(* com.example.service.*.*(..))"/> <aop:before method="beforeMethod" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config> <bean id="myAspectBean" class="com.example.aspect.MyAspect"/> ``` 在这个例子中,`MyAspect`类中的`beforeMethod`方法被定义为一个前置增强器,它将在所有`com.example.service`包下所有类的所有方法执行之前执行。 ##### 4.2 注解配置 Spring还提供了丰富的注解来简化AOP的配置。通过`@Aspect`、`@Pointcut`、`@Before`等注解,可以在Java代码中直接定义切面、切点和增强器。例如: ```java @Aspect @Component public class MyAspect { @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} @Before("serviceMethods()") public void beforeMethod() { // 前置增强逻辑 } } ``` 在这个例子中,`MyAspect`类通过`@Aspect`注解被标记为一个切面,`serviceMethods`方法通过`@Pointcut`注解定义了一个切点,而`beforeMethod`方法则通过`@Before`注解被指定为在该切点执行前的增强器。 #### 五、自动动态代理的性能考虑 虽然自动动态代理为Spring AOP提供了强大的功能,但它也会引入一定的性能开销。代理对象的创建和方法的拦截调用都会比直接调用目标对象的方法更耗时。因此,在开发过程中,应该根据实际需求合理使用AOP,避免不必要的性能损失。 - **优化切点表达式**:确保切点表达式尽可能精确,避免匹配到不需要增强的方法。 - **减少代理对象的数量**:尽量将相关的增强器组织在同一个切面中,减少代理对象的创建数量。 - **评估性能影响**:在开发过程中,使用性能测试工具评估AOP对系统性能的影响,并据此做出调整。 #### 六、总结 自动动态代理是Spring AOP实现横切关注点模块化的关键技术之一。通过动态地创建代理对象,并在方法调用前后执行特定的增强逻辑,Spring AOP为开发者提供了一种灵活且强大的方式来处理日志、事务、安全等横切关注点。在理解和掌握了自动动态代理的原理和配置方法后,开发者可以更加高效地使用Spring AOP来构建高质量、可维护的Java应用程序。
上一篇:
API实现三种After Advice
下一篇:
替换TargetSource
该分类下的相关小册推荐:
经典设计模式Java版
Java语言基础3-流程控制
Mybatis合辑2-Mybatis映射文件
JAVA 函数式编程入门与实践
Java语言基础1-基础知识
Java语言基础16-JDK8 新特性
Java语言基础11-Java中的泛型
Spring AOP 编程思想(下)
java源码学习笔记
手把手带你学习SpringBoot-零基础到实战
Java语言基础6-面向对象高级
深入理解Java虚拟机