@Around的执行流程,详细一点
时间: 2024-08-15 20:06:05 浏览: 69
YOLOv3-训练-修剪.zip
`@Around`是一种非常强大的Spring AOP(面向切面编程)注解,允许你编写环绕通知,这种通知可以在目标方法的执行前后插入额外的行为。在理解`@Around`的执行流程之前,首先需要理解几个基本概念:
- **前置通知(`@Before`)**: 该通知在目标方法执行之前执行。
- **后置通知(`@After`)**: 当目标方法正常完成(无论是否抛出异常)之后执行。
- **最终通知(`@AfterThrowing`)**: 当目标方法抛出异常时执行。
- **环绕通知(`@Around`)**: 这是最复杂的类型,在目标方法执行前后插入自定义的行为,并有权选择是否继续执行目标方法或直接返回结果而不执行目标方法本身。
### `@Around`执行流程详解:
#### 执行阶段:
1. **获取连接点(Join Point)**:当切点匹配上时,系统会自动获得当前的连接点。连接点包含了目标方法及其上下文信息。
2. **执行前置通知 (`@Before`)**:如果`@Around`注解内包含前置通知,则在目标方法执行前立即执行这部分代码。
3. **执行目标方法**:接下来,系统执行目标方法的实际代码。这包括所有嵌套的方法调用等。
4. **决策是否执行目标方法**:这是`@Around`的核心部分。环绕通知可以控制目标方法是否执行下去。默认情况下,环绕通知会继续执行目标方法。但是,环绕通知可以根据需要在目标方法执行前后插入任意逻辑,并且有权限决定是否应该继续执行目标方法。这通常涉及调用`ProceedingJoinPoint.proceed()`方法。如果没有调用此方法或者返回的是`null`,则意味着不再执行目标方法。如果调用了`proceed()`并且传递了一个参数(即一个`Object`),那么这个参数将作为目标方法的返回值。
5. **执行后置通知 (`@After`) 或最终通知 (`@AfterThrowing`)**:
- 如果目标方法成功执行完毕,那么将会执行`@After`通知。
- 如果目标方法执行过程中出现了异常,那么`@AfterThrowing`通知会被执行。
6. **结束流程**:无论目标方法是否被执行或是因异常而未执行,最终的后置通知都会执行。
### 实际示例:
下面是一个简单的`@Around`使用示例,展示了如何在方法执行前后插入额外的逻辑:
```java
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAroundAdvice {
@Around("execution(* com.example.*.*(..))") // 这里的切入点匹配所有com.example包下方法
public Object loggingAround(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
// 前置通知
System.out.println("Before Method Execution");
try {
// 获取实际方法并执行
Object result = pjp.proceed(); // 调用目标方法
// 后置通知
System.out.println("After Method Execution");
return result; // 返回目标方法的结果
} catch (Throwable e) {
// 最终通知(这里仅处理异常)
System.out.println("Error occurred during method execution: " + e.getMessage());
throw e;
} finally {
long end = System.currentTimeMillis();
System.out.println("Method took: " + (end - start) + " ms");
}
}
}
```
在上述示例中,我们使用了`@Around`来包裹一个方法,并在其前后添加了日志输出。此外,我们还捕获了任何可能发生的异常,并在finally块中进行了处理。这种结构使得我们可以灵活地在目标方法执行前后插入各种逻辑,包括但不限于性能度量、错误处理、审计等。
---
### 相关问题:
1. **如何在Spring中配置环绕通知?**
- 主要是通过创建切面类并在其中使用`@Around`注解来配置环绕通知。
2. **为什么使用环绕通知而非前置或后置通知?**
- 环绕通知提供了最大的灵活性,允许你在目标方法执行前和执行后插入任何代码,甚至决定是否执行目标方法本身,因此常用于复杂逻辑控制。
3. **如何有效地利用`ProceedingJoinPoint`?**
- `ProceedingJoinPoint`提供了一种执行目标方法的机制,通过调用`proceed()`方法并将可能的返回值作为参数传递给下一个通知,可以实现灵活的AOP控制流管理。
阅读全文