首页
技术小册
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 编程思想(上)
### 章节标题:API实现Around Advice 在Spring框架中,面向切面编程(AOP, Aspect-Oriented Programming)是一种强大的编程范式,它允许开发者将横切关注点(如日志、事务管理、安全等)从业务逻辑中分离出来,从而提高代码的可维护性、可重用性和模块化。在Spring AOP中,`Around Advice`(环绕通知)是最强大的一种通知类型,因为它能够在目标方法执行前后以及异常发生时执行自定义的代码,并且可以决定是否继续执行目标方法或中断执行。 #### 1. 环绕通知的基本概念 环绕通知是Spring AOP中最为灵活的通知类型。它允许你在目标方法执行前后插入自定义逻辑,并且可以控制目标方法的执行流程,包括是否执行目标方法本身、如何传递参数给目标方法、如何处理目标方法返回的结果或异常等。环绕通知通过`ProceedingJoinPoint`接口提供对目标方法的访问,该接口是`JoinPoint`的子接口,增加了`proceed()`方法用于执行目标方法。 #### 2. 实现环绕通知的步骤 ##### 2.1 定义切面 首先,你需要定义一个切面(Aspect),这通常是一个带有`@Aspect`注解的类。在这个类中,你可以定义各种类型的通知,包括环绕通知。 ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { // 定义一个切入点表达式,指定哪些方法会被拦截 @Pointcut("execution(* com.example.service.*.*(..))") public void serviceLayerExecution() {} // 环绕通知的实现 @Around("serviceLayerExecution()") public Object logAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { // 目标方法执行前的逻辑 System.out.println("Before executing: " + joinPoint.getSignature().getName()); try { // 调用目标方法 Object result = joinPoint.proceed(); // 目标方法执行后的逻辑 System.out.println("After executing: " + joinPoint.getSignature().getName()); return result; } catch (IllegalArgumentException e) { // 处理特定异常 System.err.println("Illegal argument: " + e.getMessage()); throw e; // 可以选择重新抛出异常或进行其他处理 } } } ``` ##### 2.2 切入点表达式 在上面的例子中,`@Pointcut`注解用于定义一个切入点表达式,该表达式指定了哪些方法将被环绕通知拦截。Spring AOP支持AspectJ的切入点表达式语言,允许你精确地指定方法的选择器。 ##### 2.3 环绕通知的方法签名 环绕通知的方法必须返回一个`Object`类型(以匹配目标方法的返回类型),并且必须声明一个`ProceedingJoinPoint`类型的参数,通过调用该参数的`proceed()`方法来执行目标方法。 ##### 2.4 异常处理 在环绕通知中,你可以捕获并处理目标方法抛出的异常。如果选择在捕获异常后继续执行后续逻辑(如记录日志后重新抛出异常),则需要注意异常类型的兼容性和传播。 #### 3. 环绕通知的高级应用 ##### 3.1 修改目标方法的返回值 环绕通知可以修改目标方法的返回值。通过在调用`proceed()`方法后获取返回值,并进行必要的修改,然后返回新的值。 ```java public Object logAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { Object result = joinPoint.proceed(); // 修改返回值 if (result instanceof String) { return ((String) result).toUpperCase(); } return result; } ``` ##### 3.2 决定是否执行目标方法 在某些情况下,你可能需要根据某些条件决定是否执行目标方法。通过在调用`proceed()`之前进行条件判断,并根据结果决定是否调用`proceed()`,可以实现这一目标。 ```java public Object conditionalExecution(ProceedingJoinPoint joinPoint) throws Throwable { if (someCondition()) { return joinPoint.proceed(); // 条件满足,执行目标方法 } else { // 条件不满足,执行替代逻辑 return "Condition not met"; } } ``` ##### 3.3 性能监控 环绕通知非常适合用于性能监控。你可以在目标方法执行前后记录时间戳,从而计算并输出目标方法的执行时间。 ```java public Object performanceMonitor(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); long endTime = System.currentTimeMillis(); System.out.println("Execution time of " + joinPoint.getSignature().getName() + ": " + (endTime - startTime) + " ms"); return result; } ``` #### 4. 注意事项 - **性能影响**:虽然环绕通知提供了极大的灵活性,但过度使用或在不必要的地方使用可能会引入性能开销。 - **异常处理**:确保在环绕通知中正确处理异常,避免隐藏或错误地传播异常。 - **代码可读性**:使用环绕通知时,保持代码清晰和可维护性非常重要。确保注释充分,并尽量将复杂的逻辑分解为可重用的方法或组件。 - **测试**:由于环绕通知可能改变目标方法的行为,因此确保进行充分的测试以验证其正确性。 #### 5. 结论 通过API实现Around Advice是Spring AOP中一个强大且灵活的功能,它允许开发者在目标方法执行前后以及异常发生时插入自定义逻辑,并控制目标方法的执行流程。通过合理使用环绕通知,可以显著提高代码的可维护性、可重用性和模块化程度。然而,也需要注意其可能带来的性能开销和复杂性,确保在必要时使用,并保持代码的清晰和可维护性。
上一篇:
XML配置Around Advice
下一篇:
@AspectJ前置动作:@Before与@Around谁优先级执行?
该分类下的相关小册推荐:
Java语言基础5-面向对象初级
Java语言基础6-面向对象高级
java源码学习笔记
Java面试指南
Java必知必会-Maven初级
Java必知必会-Maven高级
SpringBoot零基础到实战
经典设计模式Java版
SpringBoot合辑-初级篇
Java必知必会-JDBC
Spring AOP 编程思想(下)
Java语言基础10-Java中的集合