AfterReturningAdvice优化

master
linlei 2024-04-29 11:39:19 +08:00
parent 780e96a5d7
commit 0b8e2354c9
4 changed files with 110 additions and 63 deletions

View File

@ -6,8 +6,8 @@
- [三、主要功能](#三主要功能) - [三、主要功能](#三主要功能)
- [四、接口源码](#四接口源码) - [四、接口源码](#四接口源码)
- [五、主要实现](#五主要实现) - [五、主要实现](#五主要实现)
- [六、最佳实践](#六最佳实践) - [六、类关系图](#六类关系图)
- [七、常见问题](#七常见问题) - [七、最佳实践](#七最佳实践)
### 一、基本信息 ### 一、基本信息

View File

@ -6,8 +6,8 @@
- [三、主要功能](#三主要功能) - [三、主要功能](#三主要功能)
- [四、接口源码](#四接口源码) - [四、接口源码](#四接口源码)
- [五、主要实现](#五主要实现) - [五、主要实现](#五主要实现)
- [六、最佳实践](#六最佳实践) - [六、类关系图](#六类关系图)
- [七、常见问题](#七常见问题) - [七、最佳实践](#七最佳实践)
### 一、基本信息 ### 一、基本信息
@ -21,7 +21,7 @@
1. **引介新的接口或类** 1. **引介新的接口或类**
+ 通过实现 `introduce()` 方法,在目标对象的方法调用之前,向目标对象引介新的接口或类,从而使目标对象具有额外的功能或属性。 + 通过实现 `implementsInterface()` 方法,在目标对象的方法调用之前,向目标对象引介新的接口或类,从而使目标对象具有额外的功能或属性。
### 四、接口源码 ### 四、接口源码
@ -51,7 +51,44 @@ public interface IntroductionInterceptor extends MethodInterceptor, DynamicIntro
+ `DelegatePerTargetObjectIntroductionInterceptor``DelegatingIntroductionInterceptor` 的子类,为每个目标对象创建一个独立的引介代理对象。这意味着每个目标对象都可以拥有自己独立的引介逻辑,而不会受到其他目标对象的影响。这种灵活性特别适用于需要为不同的目标对象动态添加不同功能或属性的场景,提供了更高级的定制能力。 + `DelegatePerTargetObjectIntroductionInterceptor``DelegatingIntroductionInterceptor` 的子类,为每个目标对象创建一个独立的引介代理对象。这意味着每个目标对象都可以拥有自己独立的引介逻辑,而不会受到其他目标对象的影响。这种灵活性特别适用于需要为不同的目标对象动态添加不同功能或属性的场景,提供了更高级的定制能力。
### 六、最佳实践 ### 六、类关系图
~~~mermaid
classDiagram
direction BT
class Advice {
<<Interface>>
}
class DelegatePerTargetObjectIntroductionInterceptor
class DelegatingIntroductionInterceptor
class DynamicIntroductionAdvice {
<<Interface>>
}
class Interceptor {
<<Interface>>
}
class IntroductionInterceptor {
<<Interface>>
}
class MethodInterceptor {
<<Interface>>
}
DelegatePerTargetObjectIntroductionInterceptor ..> IntroductionInterceptor
DelegatingIntroductionInterceptor ..> IntroductionInterceptor
DynamicIntroductionAdvice --> Advice
Interceptor --> Advice
IntroductionInterceptor --> DynamicIntroductionAdvice
IntroductionInterceptor --> MethodInterceptor
MethodInterceptor --> Interceptor
~~~
### 七、最佳实践
使用 Spring AOP 中的引介功能。它创建了一个代理工厂,并通过设置强制使用 CGLIB 代理来创建代理对象。然后,它添加了一个通知器,将自定义的引介通知(`MyMonitoringIntroductionAdvice`)应用于目标对象(`MyService` 类),使得目标对象实现了 `MyMonitoringCapable` 接口。最后,它调用了代理对象的方法,并在必要时启用了监控功能,展示了如何在运行时动态地向目标对象引入新的功能。 使用 Spring AOP 中的引介功能。它创建了一个代理工厂,并通过设置强制使用 CGLIB 代理来创建代理对象。然后,它添加了一个通知器,将自定义的引介通知(`MyMonitoringIntroductionAdvice`)应用于目标对象(`MyService` 类),使得目标对象实现了 `MyMonitoringCapable` 接口。最后,它调用了代理对象的方法,并在必要时启用了监控功能,展示了如何在运行时动态地向目标对象引入新的功能。
@ -141,32 +178,3 @@ foo...
foo... foo...
[结束监控foo] 耗费时间1008 毫秒 [结束监控foo] 耗费时间1008 毫秒
``` ```
### 七、常见问题
1. **引介的作用和优势是什么?**
- 这个问题探讨了引介在 AOP 中的作用和优势,以及它与其他 AOP 概念(如通知、切点)的区别。
2. **如何实现引介?**
- 这个问题涉及到如何使用 `IntroductionInterceptor` 接口以及其子类来实现引介功能,以及在 Spring AOP 中如何配置和应用引介。
3. **引介和通知之间的区别是什么?**
- 这个问题探讨了引介和其他类型的通知(如前置通知、后置通知)之间的区别,以及它们在 AOP 中的不同用途。
4. **引介在哪些场景下会被使用?**
- 这个问题讨论了引介在实际开发中的应用场景,以及它如何帮助解决特定的横切关注点。
5. **引介是否有性能影响?**
- 这个问题关注引介在运行时对性能的影响,以及如何优化引介以减少潜在的性能开销。
6. **如何处理引介与目标类之间的依赖关系?**
- 这个问题涉及引介与目标类之间的依赖关系管理,以及如何确保引介逻辑能够正确地与目标类交互。
7. **引介在 Spring 中的实现原理是什么?**
- 这个问题探讨了 Spring AOP 是如何利用代理机制实现引介功能的,以及它与其他 AOP 框架的实现方式的区别。

View File

@ -33,7 +33,7 @@
* 拦截器,用于拦截接口方法调用并在目标方法之前和之后执行额外处理。 * 拦截器,用于拦截接口方法调用并在目标方法之前和之后执行额外处理。
* 这些拦截器被嵌套在目标方法之上。 * 这些拦截器被嵌套在目标方法之上。
* *
* <p>用户应该实现 {@link #invoke(MethodInvocation)} 方法来修改原始行为。例如,以下类实现了一个跟踪拦截器(跟踪所有被拦截方法的调用) * <p>用户应该实现 {@link #invoke(MethodInvocation)} 方法来修改原始行为。例如,以下类实现了一个跟踪拦截器(跟踪所有被拦截方法的调用)
* *
* @author Rod Johnson * @author Rod Johnson
*/ */
@ -56,35 +56,70 @@ public interface MethodInterceptor extends Interceptor {
1. **MethodBeforeAdviceInterceptor** 1. **MethodBeforeAdviceInterceptor**
+ 实现了前置通知的拦截器。前置通知在目标方法执行之前执行,允许我们在方法执行前插入额外的逻辑。通常用于日志记录、参数验证等场景。 + 实现了前置通知的拦截器。前置通知在目标方法执行之前执行,允许我们在方法执行前插入额外的逻辑。
2. **AfterReturningAdviceInterceptor** 2. **AfterReturningAdviceInterceptor**
+ 实现了返回后通知的拦截器。返回后通知在目标方法成功执行并返回结果后执行,允许我们在方法返回后插入额外的逻辑。通常用于日志记录、结果处理等场景。 + 实现了返回后通知的拦截器。返回后通知在目标方法成功执行并返回结果后执行,允许我们在方法返回后插入额外的逻辑。
3. **ThrowsAdviceInterceptor** 3. **ThrowsAdviceInterceptor**
+ 实现了异常抛出后通知的拦截器。异常抛出后通知在目标方法抛出异常后执行,允许我们在方法抛出异常后插入额外的逻辑。通常用于异常处理、日志记录等场景。
+ 实现了异常抛出后通知的拦截器。异常抛出后通知在目标方法抛出异常后执行,允许我们在方法抛出异常后插入额外的逻辑。
4. **AspectJAfterAdvice**
+ 实现了后置通知After Advice在目标方法执行后执行额外逻辑不影响目标方法的执行结果。
5. **AspectJAfterThrowingAdvice**
+ 实现了异常抛出后通知After Throwing Advice在目标方法抛出异常后执行额外逻辑允许处理异常或执行一些清理操作。
6. **AspectJAroundAdvice**
+ 实现了环绕通知Around Advice是最强大的一种通知类型允许在目标方法执行前后添加额外逻辑并完全控制目标方法的执行过程包括是否执行目标方法和如何处理返回值。
### 六、类关系图 ### 六、类关系图
~~~mermaid ~~~mermaid
classDiagram classDiagram
direction BT direction BT
class AfterReturningAdviceInterceptor class AbstractAspectJAdvice
class Advice {
<<Interface>>
}
class AspectJAfterAdvice
class AspectJAfterThrowingAdvice
class AspectJAroundAdvice
class Interceptor { class Interceptor {
<<Interface>> <<Interface>>
} }
class MethodBeforeAdviceInterceptor class MethodBeforeAdviceInterceptor
class AfterReturningAdviceInterceptor
class MethodInterceptor { class MethodInterceptor {
<<Interface>> <<Interface>>
} }
class ThrowsAdviceInterceptor class ThrowsAdviceInterceptor
AbstractAspectJAdvice ..> Advice
AfterReturningAdviceInterceptor ..> Advice
AfterReturningAdviceInterceptor ..> MethodInterceptor AfterReturningAdviceInterceptor ..> MethodInterceptor
AspectJAfterAdvice --> AbstractAspectJAdvice
AspectJAfterAdvice ..> Advice
AspectJAfterAdvice ..> MethodInterceptor
AspectJAfterThrowingAdvice --> AbstractAspectJAdvice
AspectJAfterThrowingAdvice ..> Advice
AspectJAfterThrowingAdvice ..> MethodInterceptor
AspectJAroundAdvice --> AbstractAspectJAdvice
AspectJAroundAdvice ..> MethodInterceptor
Interceptor --> Advice
MethodBeforeAdviceInterceptor ..> Advice
MethodBeforeAdviceInterceptor ..> MethodInterceptor MethodBeforeAdviceInterceptor ..> MethodInterceptor
MethodInterceptor --> Interceptor MethodInterceptor --> Interceptor
ThrowsAdviceInterceptor ..> Advice
ThrowsAdviceInterceptor ..> MethodInterceptor ThrowsAdviceInterceptor ..> MethodInterceptor
~~~ ~~~

View File

@ -6,8 +6,8 @@
- [三、主要功能](#三主要功能) - [三、主要功能](#三主要功能)
- [四、接口源码](#四接口源码) - [四、接口源码](#四接口源码)
- [五、主要实现](#五主要实现) - [五、主要实现](#五主要实现)
- [六、最佳实践](#六最佳实践) - [六、类关系图](#六类关系图)
- [七、常见问题](#七常见问题) - [七、最佳实践](#七最佳实践)
### 一、基本信息 ### 一、基本信息
@ -77,7 +77,29 @@ public interface ThrowsAdvice extends AfterAdvice {
1. **ThrowsAdviceInterceptor** 1. **ThrowsAdviceInterceptor**
+ 用于拦截方法抛出的异常,并触发相应的异常通知(`ThrowsAdvice`)。它负责捕获方法执行过程中抛出的异常,并调用相关的异常通知来处理异常情况。 + 用于拦截方法抛出的异常,并触发相应的异常通知(`ThrowsAdvice`)。它负责捕获方法执行过程中抛出的异常,并调用相关的异常通知来处理异常情况。
### 六、最佳实践 ### 六、类关系图
~~~mermaid
classDiagram
direction BT
class Advice {
<<Interface>>
}
class AfterAdvice {
<<Interface>>
}
class ThrowsAdvice {
<<Interface>>
}
AfterAdvice --> Advice
ThrowsAdvice --> AfterAdvice
~~~
### 七、最佳实践
使用`ThrowsAdvice`接口来处理方法抛出的异常。它创建了一个代理工厂,并将目标对象(`MyService`)和异常通知(`MyThrowsAdvice`)传递给代理工厂。然后,它通过代理工厂获取代理对象,并调用代理对象的方法`foo()`。 使用`ThrowsAdvice`接口来处理方法抛出的异常。它创建了一个代理工厂,并将目标对象(`MyService`)和异常通知(`MyThrowsAdvice`)传递给代理工厂。然后,它通过代理工厂获取代理对象,并调用代理对象的方法`foo()`。
@ -138,21 +160,3 @@ Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.xcs.spring.MyService$$EnhancerBySpringCGLIB$$abe9fbc2.doSomethingException(<generated>) at com.xcs.spring.MyService$$EnhancerBySpringCGLIB$$abe9fbc2.doSomethingException(<generated>)
at com.xcs.spring.ThrowsAdviceDemo.main(ThrowsAdviceDemo.java:15) at com.xcs.spring.ThrowsAdviceDemo.main(ThrowsAdviceDemo.java:15)
``` ```
### 七、常见问题
1. **异常处理的影响范围**
+ 异常通知对整个目标方法的异常都起作用,这可能不是所期望的行为。有时候可能只想针对特定类型的异常执行特定的处理逻辑。
2. **异常信息的捕获和处理**
+ 在异常通知中捕获到的异常信息可能不够详细,特别是对于大型应用程序中的复杂异常场景,可能需要更多的异常信息来进行适当的处理。
3. **异常类型的匹配**
+ 在异常通知中定义的异常类型需要与目标方法抛出的异常类型匹配,否则可能无法正确执行异常处理逻辑。
4. **对目标方法参数的访问**
+ 在异常通知中可以访问目标方法的参数,但需要小心处理参数可能为空的情况,以避免出现空指针异常。