>
+
+}
+class AspectJAfterReturningAdvice
+
+AfterAdvice --> Advice
+AfterReturningAdvice --> AfterAdvice
+AspectJAfterReturningAdvice ..> Advice
+AspectJAfterReturningAdvice ..> AfterAdvice
+AspectJAfterReturningAdvice ..> AfterReturningAdvice
+~~~
+
+### 七、最佳实践
+
+使用Spring AOP中的后置返回通知(AfterReturningAdvice)。首先,创建了一个代理工厂(ProxyFactory)并指定目标对象(MyService)。然后,创建了一个后置返回通知(MyAfterReturningAdvice)并添加到代理工厂中。接着,通过代理工厂获取代理对象,并调用代理对象的方法。
+
+```java
+public class AfterReturningAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyAfterReturningAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
+```
+
+`MyAfterReturningAdvice`的类,它实现了Spring AOP框架中的`AfterReturningAdvice`接口。在`afterReturning`方法中,当目标方法成功返回结果时,它将打印出目标方法的名称以及返回的值。
+
+```java
+public class MyAfterReturningAdvice implements AfterReturningAdvice {
+ @Override
+ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
+ System.out.println("After Method " + method.getName());
+ }
+}
+```
+
+`MyService` 类是一个简单的服务类,其中包含了一个名为 `foo()` 的方法。在上下文中,`MyService` 类被用作目标对象,即需要被拦截和增强的对象。
+
+```java
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
+```
+
+运行结果,成功地执行了代理对象的`foo()`方法,并在方法执行完成后,后置返回通知`MyAfterReturningAdvice`被触发。
+
+```java
+foo...
+After Method foo
+```
diff --git a/spring-aop/spring-aop-advice-afterReturningAdvice/pom.xml b/spring-aop/spring-aop-advice-afterReturningAdvice/pom.xml
new file mode 100644
index 00000000..cc9253b7
--- /dev/null
+++ b/spring-aop/spring-aop-advice-afterReturningAdvice/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice-afterReturningAdvice
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/AfterReturningAdviceDemo.java b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/AfterReturningAdviceDemo.java
new file mode 100644
index 00000000..e36cc097
--- /dev/null
+++ b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/AfterReturningAdviceDemo.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+
+public class AfterReturningAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyAfterReturningAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java
new file mode 100644
index 00000000..09844978
--- /dev/null
+++ b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java
@@ -0,0 +1,12 @@
+package com.xcs.spring;
+
+import org.springframework.aop.AfterReturningAdvice;
+
+import java.lang.reflect.Method;
+
+public class MyAfterReturningAdvice implements AfterReturningAdvice {
+ @Override
+ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
+ System.out.println("After Method " + method.getName());
+ }
+}
diff --git a/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..b4047e75
--- /dev/null
+++ b/spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,8 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/README.md b/spring-aop/spring-aop-advice-introductionInterceptor/README.md
new file mode 100644
index 00000000..6fab5a76
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/README.md
@@ -0,0 +1,180 @@
+## IntroductionInterceptor
+
+- [IntroductionInterceptor](#introductioninterceptor)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`IntroductionInterceptor` 接口是 Spring AOP 中的一个关键接口,用于实现引介(Introduction)功能,允许向目标对象动态地添加新的方法或属性,而无需修改目标类的代码,从而实现横切关注点的功能,如日志记录、事务管理等。
+
+### 三、主要功能
+
+1. **引介新的接口或类**
+
+ + 通过实现 `implementsInterface()` 方法,在目标对象的方法调用之前,向目标对象引介新的接口或类,从而使目标对象具有额外的功能或属性。
+
+### 四、接口源码
+
+`IntroductionInterceptor` 接口,它是 AOP 联盟 `MethodInterceptor` 的子接口,允许拦截器实现额外的接口,并通过使用该拦截器的代理对象来使用这些接口。`IntroductionInterceptor` 接口体现了 AOP 中的引介(Introduction)概念,通过引介,可以将额外的功能添加到目标对象中,类似于混合(mixins)的概念,使得可以构建复合对象,实现类似于 Java 中多继承的目标。
+
+```java
+/**
+ * AOP联盟 MethodInterceptor 的子接口,允许拦截器实现额外的接口,并通过使用该拦截器的代理对象来使用这些接口。这是一个基本的AOP概念,称为引介。
+ *
+ * 引介通常是混合,允许构建能够实现多继承目标的复合对象。
+ *
+ * @author Rod Johnson
+ * @see DynamicIntroductionAdvice
+ */
+public interface IntroductionInterceptor extends MethodInterceptor, DynamicIntroductionAdvice {
+
+}
+```
+
+### 五、主要实现
+
+1. **DelegatingIntroductionInterceptor**
+
+ + `DelegatingIntroductionInterceptor` 是 Spring AOP 提供的通用引介拦截器,允许我们定义自定义的引介逻辑,并在需要时将其应用于目标对象。通过配置,可以动态地向目标对象添加新的方法或属性,而不必修改目标类的代码,提高了代码的可维护性和灵活性。
+
+2. **DelegatePerTargetObjectIntroductionInterceptor**
+
+ + `DelegatePerTargetObjectIntroductionInterceptor` 是 `DelegatingIntroductionInterceptor` 的子类,为每个目标对象创建一个独立的引介代理对象。这意味着每个目标对象都可以拥有自己独立的引介逻辑,而不会受到其他目标对象的影响。这种灵活性特别适用于需要为不同的目标对象动态添加不同功能或属性的场景,提供了更高级的定制能力。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advice {
+<>
+
+}
+class DelegatePerTargetObjectIntroductionInterceptor
+class DelegatingIntroductionInterceptor
+class DynamicIntroductionAdvice {
+<>
+
+}
+class Interceptor {
+<>
+
+}
+class IntroductionInterceptor {
+<>
+
+}
+class MethodInterceptor {
+<>
+
+}
+
+DelegatePerTargetObjectIntroductionInterceptor ..> IntroductionInterceptor
+DelegatingIntroductionInterceptor ..> IntroductionInterceptor
+DynamicIntroductionAdvice --> Advice
+Interceptor --> Advice
+IntroductionInterceptor --> DynamicIntroductionAdvice
+IntroductionInterceptor --> MethodInterceptor
+MethodInterceptor --> Interceptor
+~~~
+
+### 七、最佳实践
+
+使用 Spring AOP 中的引介功能。它创建了一个代理工厂,并通过设置强制使用 CGLIB 代理来创建代理对象。然后,它添加了一个通知器,将自定义的引介通知(`MyMonitoringIntroductionAdvice`)应用于目标对象(`MyService` 类),使得目标对象实现了 `MyMonitoringCapable` 接口。最后,它调用了代理对象的方法,并在必要时启用了监控功能,展示了如何在运行时动态地向目标对象引入新的功能。
+
+```java
+public class IntroductionInterceptorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 强制私用CGLIB
+ proxyFactory.setProxyTargetClass(true);
+ // 创建通知
+ proxyFactory.addAdvisor(new DefaultIntroductionAdvisor(new MyMonitoringIntroductionAdvice(), MyMonitoringCapable.class));
+ // 创建代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ // 开始监控
+ ((MyMonitoringCapable) proxy).toggleMonitoring();
+ // 再次调用代理对象的方法
+ proxy.foo();
+ }
+}
+```
+
+`MyMonitoringIntroductionAdvice` 类是一个实现了 `DelegatingIntroductionInterceptor` 接口和 `MyMonitoringCapable` 接口的自定义引介通知类。它具有一个 `active` 属性来表示监控是否处于激活状态,并提供了一个方法 `toggleMonitoring()` 来启用监控功能。在被监控的方法被调用时,如果监控处于激活状态,该类会输出相应的日志信息,包括方法执行时间等。通过继承 `doProceed()` 方法,它能够在方法执行前后添加自定义逻辑,实现了监控功能的动态引入。
+
+```java
+public class MyMonitoringIntroductionAdvice extends DelegatingIntroductionInterceptor implements MyMonitoringCapable {
+
+ private boolean active = false;
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ @Override
+ public void toggleMonitoring() {
+ setActive(true);
+ }
+
+ // 当被监控的方法被调用时,如果监控处于激活状态,则输出日志
+ @Override
+ protected Object doProceed(MethodInvocation mi) throws Throwable {
+ if (this.active) {
+ System.out.println("[开启监控" + mi.getMethod().getName() + "]");
+ long startTime = System.currentTimeMillis();
+ Object result = super.doProceed(mi);
+ long endTime = System.currentTimeMillis();
+ System.out.println("[结束监控" + mi.getMethod().getName() + "] 耗费时间:" + (endTime - startTime) + " 毫秒");
+ return result;
+ }
+ return super.doProceed(mi);
+ }
+}
+```
+
+`MyMonitoringCapable` 接口定义了一个 `toggleMonitoring()` 方法,用于启用或禁用监控功能。
+
+```java
+public interface MyMonitoringCapable {
+ void toggleMonitoring();
+}
+```
+
+`MyService` 类是一个简单的服务类,其中包含了一个名为 `foo()` 的方法。在上下文中,`MyService` 类被用作目标对象,即需要被拦截和增强的对象。
+
+```java
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
+```
+
+运行结果,这个运行结果说明了引介通知成功地增强了目标方法,实现了在目标方法执行前后动态地添加额外的逻辑。
+
+```java
+foo...
+[开启监控foo]
+foo...
+[结束监控foo] 耗费时间:1008 毫秒
+```
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/pom.xml b/spring-aop/spring-aop-advice-introductionInterceptor/pom.xml
new file mode 100644
index 00000000..6c6c0a8d
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice-introductionInterceptor
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/IntroductionInterceptorDemo.java b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/IntroductionInterceptorDemo.java
new file mode 100644
index 00000000..c4dd7bf6
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/IntroductionInterceptorDemo.java
@@ -0,0 +1,24 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.aop.support.DefaultIntroductionAdvisor;
+
+public class IntroductionInterceptorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 强制私用CGLIB
+ proxyFactory.setProxyTargetClass(true);
+ // 创建通知
+ proxyFactory.addAdvisor(new DefaultIntroductionAdvisor(new MyMonitoringIntroductionAdvice(), MyMonitoringCapable.class));
+ // 创建代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ // 开始监控
+ ((MyMonitoringCapable) proxy).toggleMonitoring();
+ // 再次调用代理对象的方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringCapable.java b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringCapable.java
new file mode 100644
index 00000000..7bc345c7
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringCapable.java
@@ -0,0 +1,5 @@
+package com.xcs.spring;
+
+public interface MyMonitoringCapable {
+ void toggleMonitoring();
+}
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringIntroductionAdvice.java b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringIntroductionAdvice.java
new file mode 100644
index 00000000..fb19cd70
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringIntroductionAdvice.java
@@ -0,0 +1,32 @@
+package com.xcs.spring;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.aop.support.DelegatingIntroductionInterceptor;
+
+public class MyMonitoringIntroductionAdvice extends DelegatingIntroductionInterceptor implements MyMonitoringCapable {
+
+ private boolean active = false;
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ @Override
+ public void toggleMonitoring() {
+ setActive(true);
+ }
+
+ // 当被监控的方法被调用时,如果监控处于激活状态,则输出日志
+ @Override
+ protected Object doProceed(MethodInvocation mi) throws Throwable {
+ if (this.active) {
+ System.out.println("[开启监控" + mi.getMethod().getName() + "]");
+ long startTime = System.currentTimeMillis();
+ Object result = super.doProceed(mi);
+ long endTime = System.currentTimeMillis();
+ System.out.println("[结束监控" + mi.getMethod().getName() + "] 耗费时间:" + (endTime - startTime) + " 毫秒");
+ return result;
+ }
+ return super.doProceed(mi);
+ }
+}
diff --git a/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..7ecc3942
--- /dev/null
+++ b/spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,13 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodBeforeAdvice/README.md b/spring-aop/spring-aop-advice-methodBeforeAdvice/README.md
new file mode 100644
index 00000000..82bde6b5
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodBeforeAdvice/README.md
@@ -0,0 +1,142 @@
+## MethodBeforeAdvice
+
+- [MethodBeforeAdvice](#methodbeforeadvice)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`MethodBeforeAdvice`接口是Spring AOP中的一个核心接口,允许我们在目标方法执行之前插入自定义的逻辑,例如参数验证、日志记录等,从而实现面向切面编程的前置通知功能。
+
+### 三、主要功能
+
+1. **前置通知**
+
+ + 允许我们在目标方法执行之前执行额外的逻辑操作。
+
+2. **横切关注点的分离**
+
+ + 将与业务逻辑无关的横切关注点(如日志记录、性能监控、安全验证等)与核心业务逻辑分离开来,提高代码的模块化和可维护性。
+
+3. **参数验证**
+
+ + 在目标方法执行前对方法参数进行验证,确保参数的合法性。
+
+4. **权限控制**
+
+ + 在方法执行前进行权限检查,确保只有具有足够权限的用户能够执行该方法。
+
+### 四、接口源码
+
+`MethodBeforeAdvice`接口,用于在方法调用之前执行通知。通知方法`before`接收被调用的方法、方法参数以及方法调用的目标对象作为参数,并可以抛出Throwable以中止方法调用。这样的通知无法阻止方法调用的继续进行,除非它们抛出了Throwable。
+
+```java
+/**
+ * 在方法被调用之前调用的通知。这样的通知不能阻止方法调用的继续进行,除非它们抛出了一个Throwable。
+ *
+ * @author Rod Johnson
+ * @see AfterReturningAdvice
+ * @see ThrowsAdvice
+ */
+public interface MethodBeforeAdvice extends BeforeAdvice {
+
+ /**
+ * 在给定方法被调用之前的回调。
+ * @param method 被调用的方法
+ * @param args 方法的参数
+ * @param target 方法调用的目标对象。可能为 {@code null}。
+ * @throws Throwable 如果此对象希望中止调用。任何抛出的异常如果方法签名允许,将返回给调用者。否则异常将作为运行时异常进行包装。
+ */
+ void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
+
+}
+```
+
+### 五、主要实现
+
+1. **AspectJMethodBeforeAdvice**
+
+ - 实现了前置通知,使用 AspectJ 风格定义的通知,用于在目标方法执行前执行额外的逻辑。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advice {
+<>
+
+}
+class AspectJMethodBeforeAdvice
+class BeforeAdvice {
+<>
+
+}
+class MethodBeforeAdvice {
+<>
+
+}
+
+AspectJMethodBeforeAdvice ..> Advice
+AspectJMethodBeforeAdvice ..> MethodBeforeAdvice
+BeforeAdvice --> Advice
+MethodBeforeAdvice --> BeforeAdvice
+~~~
+
+### 七、最佳实践
+
+使用`MethodBeforeAdvice`接口。首先,通过创建代理工厂和目标对象,然后创建自定义的前置通知`MyMethodBeforeAdvice`,将其添加到代理工厂中。接着,通过代理工厂获取代理对象,并调用代理对象的方法。在方法调用之前,前置通知会被触发执行,执行自定义的逻辑。
+
+```java
+public class MethodBeforeAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyMethodBeforeAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.doSomething();
+ }
+}
+```
+
+`MyMethodBeforeAdvice`类实现了`MethodBeforeAdvice`接口,在其`before`方法中,打印出目标方法被调用之前的信息,包括方法名。这个类可以用作Spring AOP中的前置通知,在目标方法执行之前执行一些额外的逻辑。
+
+```java
+public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
+ @Override
+ public void before(Method method, Object[] args, Object target) throws Throwable {
+ System.out.println("Before Method " + method.getName());
+ }
+}
+```
+
+`MyService` 类是一个简单的服务类,其中包含了一个名为 `doSomething()` 的方法。在上下文中,`MyService` 类被用作目标对象,即需要被拦截和增强的对象。
+
+```java
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
+```
+
+运行结果,调用目标方法`foo`之前,`MyMethodBeforeAdvice`中的前置通知被成功触发,并打印了相应的信息。
+
+```java
+Before Method foo
+foo...
+```
diff --git a/spring-aop/spring-aop-advice-methodBeforeAdvice/pom.xml b/spring-aop/spring-aop-advice-methodBeforeAdvice/pom.xml
new file mode 100644
index 00000000..0e7e8ceb
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodBeforeAdvice/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice-methodBeforeAdvice
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MethodBeforeAdviceDemo.java b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MethodBeforeAdviceDemo.java
new file mode 100644
index 00000000..d8370560
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MethodBeforeAdviceDemo.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+
+public class MethodBeforeAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyMethodBeforeAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
new file mode 100644
index 00000000..1b06dc30
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
@@ -0,0 +1,12 @@
+package com.xcs.spring;
+
+import org.springframework.aop.MethodBeforeAdvice;
+
+import java.lang.reflect.Method;
+
+public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
+ @Override
+ public void before(Method method, Object[] args, Object target) throws Throwable {
+ System.out.println("Before Method " + method.getName());
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..b4047e75
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,8 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodInterceptor/README.md b/spring-aop/spring-aop-advice-methodInterceptor/README.md
new file mode 100644
index 00000000..49c1e060
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodInterceptor/README.md
@@ -0,0 +1,181 @@
+## MethodInterceptor
+
+- [MethodInterceptor](#methodinterceptor)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`MethodInterceptor`接口是Spring框架中的一个核心接口,用于实现面向切面编程(AOP)。通过实现该接口,可以在目标方法执行前后、异常抛出时等关键点对方法进行拦截和增强,从而实现横切关注点的集中管理,提高代码的可维护性和灵活性。
+
+### 三、主要功能
+
+1. **方法拦截和增强**
+
+ + 可以在目标方法执行前后、异常抛出时等关键点对方法进行拦截和增强,从而实现横切关注点的代码集中管理。
+
+### 四、接口源码
+
+`MethodInterceptor`接口是用于拦截接口方法调用并在目标方法之前和之后执行额外处理的核心接口。我们需要实现其中的`invoke`方法来定义拦截器的具体行为,例如,可以实现一个跟踪拦截器来追踪被拦截方法的调用情况。在`invoke`方法中,通常会调用`proceed()`方法来继续执行目标方法,并在必要时对返回值或异常进行处理。
+
+```java
+/**
+ * 拦截器,用于拦截接口方法调用并在目标方法之前和之后执行额外处理。
+ * 这些拦截器被嵌套在目标方法之上。
+ *
+ * 用户应该实现 {@link #invoke(MethodInvocation)} 方法来修改原始行为。例如,以下类实现了一个跟踪拦截器(跟踪所有被拦截方法的调用)
+ *
+ * @author Rod Johnson
+ */
+@FunctionalInterface
+public interface MethodInterceptor extends Interceptor {
+
+ /**
+ * 实现此方法以在调用之前和之后执行额外处理。礼貌的实现应该肯定地调用 {@link Joinpoint#proceed()}。
+ * @param invocation 方法调用连接点
+ * @return 调用 {@link Joinpoint#proceed()} 的结果;可能会被拦截器拦截
+ * @throws Throwable 如果拦截器或目标对象抛出异常
+ */
+ @Nullable
+ Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;
+
+}
+```
+
+### 五、主要实现
+
+1. **MethodBeforeAdviceInterceptor**
+
+ + 实现了前置通知的拦截器。前置通知在目标方法执行之前执行,允许我们在方法执行前插入额外的逻辑。
+
+2. **AfterReturningAdviceInterceptor**
+
+ + 实现了返回后通知的拦截器。返回后通知在目标方法成功执行并返回结果后执行,允许我们在方法返回后插入额外的逻辑。
+
+3. **ThrowsAdviceInterceptor**
+
+ + 实现了异常抛出后通知的拦截器。异常抛出后通知在目标方法抛出异常后执行,允许我们在方法抛出异常后插入额外的逻辑。
+
+4. **AspectJAfterAdvice**
+
+ + 实现了后置通知(After Advice),在目标方法执行后执行额外逻辑,不影响目标方法的执行结果。
+
+5. **AspectJAfterThrowingAdvice**
+
+ + 实现了异常抛出后通知(After Throwing Advice),在目标方法抛出异常后执行额外逻辑,允许处理异常或执行一些清理操作。
+
+6. **AspectJAroundAdvice**
+
+ + 实现了环绕通知(Around Advice),是最强大的一种通知类型,允许在目标方法执行前后添加额外逻辑,并完全控制目标方法的执行过程,包括是否执行目标方法和如何处理返回值。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class AbstractAspectJAdvice
+class Advice {
+<>
+
+}
+
+class AspectJAfterAdvice
+class AspectJAfterThrowingAdvice
+class AspectJAroundAdvice
+class Interceptor {
+<>
+
+}
+class MethodBeforeAdviceInterceptor
+class AfterReturningAdviceInterceptor
+class MethodInterceptor {
+<>
+
+}
+class ThrowsAdviceInterceptor
+
+AbstractAspectJAdvice ..> Advice
+AfterReturningAdviceInterceptor ..> Advice
+AfterReturningAdviceInterceptor ..> MethodInterceptor
+AspectJAfterAdvice --> AbstractAspectJAdvice
+AspectJAfterAdvice ..> Advice
+AspectJAfterAdvice ..> MethodInterceptor
+AspectJAfterThrowingAdvice --> AbstractAspectJAdvice
+AspectJAfterThrowingAdvice ..> Advice
+AspectJAfterThrowingAdvice ..> MethodInterceptor
+AspectJAroundAdvice --> AbstractAspectJAdvice
+AspectJAroundAdvice ..> MethodInterceptor
+Interceptor --> Advice
+MethodBeforeAdviceInterceptor ..> Advice
+MethodBeforeAdviceInterceptor ..> MethodInterceptor
+MethodInterceptor --> Interceptor
+ThrowsAdviceInterceptor ..> Advice
+ThrowsAdviceInterceptor ..> MethodInterceptor
+~~~
+
+
+### 七、最佳实践
+
+创建了一个代理工厂 `ProxyFactory`,并传入了目标对象 `MyService`。然后通过 `proxyFactory.addAdvice()` 方法添加了一个自定义的方法拦截器 `MyMethodInterceptor` 作为通知。接着,通过 `proxyFactory.getProxy()` 方法获取代理对象 `MyService` 的实例。最后,调用代理对象的方法 `doSomething()`。
+
+```java
+public class MethodInterceptorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyMethodInterceptor());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
+```
+
+`MyMethodInterceptor` 类用于实现方法拦截和增强的功能。在 `invoke()` 方法中,首先通过 `MethodInvocation` 对象获取被调用方法的信息,例如方法名等,并在方法调用之前输出方法被调用的信息。然后调用 `invocation.proceed()` 方法来执行原始方法,获取方法执行结果。最后并将其返回。
+
+```java
+public class MyMethodInterceptor implements MethodInterceptor {
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ // 在方法调用之前执行的逻辑
+ System.out.println("Before Method " + invocation.getMethod().getName());
+ // 调用原始方法
+ Object result = invocation.proceed();
+ // 在方法调用之后执行的逻辑
+ System.out.println("After Method " + invocation.getMethod().getName());
+ return result;
+ }
+}
+```
+
+`MyService` 类是一个简单的服务类,其中包含了一个名为 `foo()` 的方法。在上下文中,`MyService` 类被用作目标对象,即需要被拦截和增强的对象。
+
+```java
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
+```
+
+运行结果,在调用 `MyService` 实例的 `foo()` 方法时,`MyMethodInterceptor` 拦截器成功地拦截了方法的执行,并在方法执行前后添加了额外的逻辑处理。
+
+```java
+Before Method foo
+foo...
+After Method foo
+```
diff --git a/spring-aop/spring-aop-advice-methodInterceptor/pom.xml b/spring-aop/spring-aop-advice-methodInterceptor/pom.xml
new file mode 100644
index 00000000..ce6dd97a
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodInterceptor/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice-methodInterceptor
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MethodInterceptorDemo.java b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MethodInterceptorDemo.java
new file mode 100644
index 00000000..bdd9c5b7
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MethodInterceptorDemo.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+
+public class MethodInterceptorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyMethodInterceptor());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java
new file mode 100644
index 00000000..55b4b850
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+public class MyMethodInterceptor implements MethodInterceptor {
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ // 在方法调用之前执行的逻辑
+ System.out.println("Before Method " + invocation.getMethod().getName());
+ // 调用原始方法
+ Object result = invocation.proceed();
+ // 在方法调用之后执行的逻辑
+ System.out.println("After Method " + invocation.getMethod().getName());
+ return result;
+ }
+}
diff --git a/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..b4047e75
--- /dev/null
+++ b/spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,8 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
diff --git a/spring-aop/spring-aop-advice-throwsAdvice/README.md b/spring-aop/spring-aop-advice-throwsAdvice/README.md
new file mode 100644
index 00000000..94c55e66
--- /dev/null
+++ b/spring-aop/spring-aop-advice-throwsAdvice/README.md
@@ -0,0 +1,162 @@
+## ThrowsAdvice
+
+- [ThrowsAdvice](#throwsadvice)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`ThrowsAdvice`接口是Spring AOP中的一种通知类型,用于在方法抛出异常时执行额外的逻辑。实现该接口的类可以捕获方法抛出的异常并执行自定义的异常处理逻辑。
+
+### 三、主要功能
+
+1. **捕获异常**
+
+ + 允许在目标方法抛出异常时捕获这些异常。
+
+2. **执行额外逻辑**
+
+ + 提供了`afterThrowing()`方法,允许实现类在方法抛出异常时执行额外的逻辑,比如记录日志、发送通知等。
+
+3. **参数传递**
+
+ + `afterThrowing()`方法提供了抛出异常的方法对象、参数数组、目标对象和异常对象作为参数,方便实现类在处理异常时获取相关信息。
+
+4. **定制化处理**
+
+ + 可以根据业务需求定制化异常处理逻辑,使应用程序更加灵活和健壮。
+
+### 四、接口源码
+
+`ThrowsAdvice`接口,用作异常通知的标签接口。它没有任何方法,方法是通过反射调用的。实现类必须实现`afterThrowing()`方法,以处理方法抛出的异常。该方法的参数形式为`void afterThrowing([Method, args, target], ThrowableSubclass)`,前三个参数可选,用于提供关于连接点的更多信息,
+
+```java
+/**
+ * 用于异常通知的标签接口。
+ *
+ * 该接口没有任何方法,因为方法是通过反射调用的。实现类必须实现以下形式的方法:
+ *
+ *
void afterThrowing([Method, args, target], ThrowableSubclass);
+ *
+ * 以下是一些有效的方法示例:
+ *
+ *
public void afterThrowing(Exception ex)
+ * public void afterThrowing(RemoteException)
+ * public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
+ * public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)
+ *
+ * 前三个参数是可选的,只有在我们需要有关连接点更多信息时才有用,如AspectJ中的after-throwing通知。
+ *
+ * 注意: 如果throws-advice方法本身抛出异常,它将覆盖原始异常(即将异常更改为用户)。
+ * 覆盖的异常通常是RuntimeException; 这与任何方法签名兼容。但是,如果throws-advice方法抛出一个已检查的异常,
+ * 它将必须匹配目标方法的声明异常,并且在某种程度上与特定目标方法签名耦合。
+ * 不要抛出与目标方法签名不兼容的未声明的检查异常!
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @see AfterReturningAdvice
+ * @see MethodBeforeAdvice
+ */
+public interface ThrowsAdvice extends AfterAdvice {
+
+}
+```
+
+### 五、主要实现
+
+1. **ThrowsAdviceInterceptor**
+ + 用于拦截方法抛出的异常,并触发相应的异常通知(`ThrowsAdvice`)。它负责捕获方法执行过程中抛出的异常,并调用相关的异常通知来处理异常情况。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advice {
+<>
+
+}
+class AfterAdvice {
+<>
+
+}
+class ThrowsAdvice {
+<>
+
+}
+
+AfterAdvice --> Advice
+ThrowsAdvice --> AfterAdvice
+~~~
+
+### 七、最佳实践
+
+使用`ThrowsAdvice`接口来处理方法抛出的异常。它创建了一个代理工厂,并将目标对象(`MyService`)和异常通知(`MyThrowsAdvice`)传递给代理工厂。然后,它通过代理工厂获取代理对象,并调用代理对象的方法`foo()`。
+
+```java
+public class ThrowsAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyThrowsAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
+```
+
+`MyThrowsAdvice`类实现了`ThrowsAdvice`接口,并定义了`afterThrowing()`方法,用于处理方法抛出的异常。当目标方法抛出异常时,该方法将被调用,并打印出异常信息。
+
+```java
+public class MyThrowsAdvice implements ThrowsAdvice {
+ public void afterThrowing(Exception ex) throws Throwable {
+ System.out.println("Exception thrown: " + ex.getMessage());
+ }
+}
+```
+
+`MyService`类包含了一个名为`foo()`的方法,该方法执行某些操作,并故意引发了一个异常(通过除以零)。
+
+```java
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ int i = 1 / 0;
+ }
+}
+```
+
+运行结果,当调用了`MyService`类的`foo()`方法,但在该方法中发生了除以零的错误,导致了`java.lang.ArithmeticException: / by zero`异常的抛出。
+
+```java
+Doing something exception...
+Exception thrown: / by zero
+Exception in thread "main" java.lang.ArithmeticException: / by zero
+ at com.xcs.spring.MyService.doSomethingException(MyService.java:7)
+ at com.xcs.spring.MyService$$FastClassBySpringCGLIB$$c768e93b.invoke()
+ at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
+ at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
+ at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
+ at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
+ at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:113)
+ at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
+ at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
+ at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
+ at com.xcs.spring.MyService$$EnhancerBySpringCGLIB$$abe9fbc2.doSomethingException()
+ at com.xcs.spring.ThrowsAdviceDemo.main(ThrowsAdviceDemo.java:15)
+```
diff --git a/spring-aop/spring-aop-advice-throwsAdvice/pom.xml b/spring-aop/spring-aop-advice-throwsAdvice/pom.xml
new file mode 100644
index 00000000..1b3cc176
--- /dev/null
+++ b/spring-aop/spring-aop-advice-throwsAdvice/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice-throwsAdvice
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..c33b29f1
--- /dev/null
+++ b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,9 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ public void foo() {
+ System.out.println("foo...");
+ int i = 1 / 0;
+ }
+}
diff --git a/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyThrowsAdvice.java b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyThrowsAdvice.java
new file mode 100644
index 00000000..b26e5653
--- /dev/null
+++ b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyThrowsAdvice.java
@@ -0,0 +1,9 @@
+package com.xcs.spring;
+
+import org.springframework.aop.ThrowsAdvice;
+
+public class MyThrowsAdvice implements ThrowsAdvice {
+ public void afterThrowing(Exception ex) throws Throwable {
+ System.out.println("Exception thrown: " + ex.getMessage());
+ }
+}
diff --git a/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/ThrowsAdviceDemo.java b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/ThrowsAdviceDemo.java
new file mode 100644
index 00000000..4c5d7d3c
--- /dev/null
+++ b/spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/ThrowsAdviceDemo.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+
+public class ThrowsAdviceDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂&创建目标对象
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 创建通知
+ proxyFactory.addAdvice(new MyThrowsAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用代理对象的方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advice/README.md b/spring-aop/spring-aop-advice/README.md
new file mode 100644
index 00000000..8da205d0
--- /dev/null
+++ b/spring-aop/spring-aop-advice/README.md
@@ -0,0 +1,152 @@
+## Advice
+
+- [Advice](#advice)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、子接口](#五子接口)
+ - [六、类关系图](#六类关系图)
+
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`Advice`接口是Spring AOP中的核心接口之一,用于定义在切面逻辑中要执行的操作。它允许我们在目标方法执行前、执行后、抛出异常时等不同的连接点上添加自定义的行为。`Advice`接口的实现类可以通过方法拦截器(MethodInterceptor)、前置通知(BeforeAdvice)、后置通知(AfterReturningAdvice)、异常通知(ThrowsAdvice)等方式来实现不同类型的通知逻辑。
+
+### 三、主要功能
+
+1. **定义通知逻辑**
+
+ + 允许我们定义在目标方法执行前、执行后、抛出异常时等不同连接点上执行的操作。
+
+2. **支持不同类型的通知**
+
+ + `Advice`接口的实现类可以实现不同类型的通知逻辑,如前置通知、后置通知、环绕通知、异常通知等。
+
+3. **与切点结合**
+
+ + `Advice`通常与切点(Pointcut)结合使用,以确定通知应该在哪些连接点上执行。
+
+4. **应用于Advisor**
+
+ + `Advice`通常作为`Advisor`的一部分,与切点结合,以实现切面的逻辑。
+
+### 四、接口源码
+
+`Advice`接口是Spring AOP中的一个标签接口,用于定义各种类型的通知,例如拦截器。通过实现该接口,我们可以定义在方法执行前、执行后、抛出异常时等不同连接点上执行的操作,从而实现对应用程序行为的干预和控制。
+
+```java
+/**
+ * Advice的标签接口。实现可以是任何类型的通知,例如拦截器。
+ *
+ * 该接口用于定义通知。通知可以是在方法执行前、执行后、抛出异常时等不同连接点上执行的操作。
+ * 实现该接口的类可以是拦截器(Interceptors)等任何类型的通知。
+ *
+ * @author Rod Johnson
+ * @version $Id: Advice.java,v 1.1 2004/03/19 17:02:16 johnsonr Exp $
+ */
+public interface Advice {
+
+}
+```
+
+### 五、子接口
+
+1. **AfterAdvice(后置通知)**
+
+ + 是一个标记接口,用于表示后置通知的类型。
+
+2. **AfterReturningAdvice(返回后通知)**
+
+ + 用于在目标方法成功执行并返回结果后执行自定义逻辑。
+
+3. **BeforeAdvice(前置通知)**
+
+ + 用于在目标方法执行前执行自定义逻辑。
+
+4. **ConstructorInterceptor(构造器拦截器)**
+
+ + 实现该接口的类可以在目标对象的构造器被调用时执行自定义逻辑。
+
+5. **Interceptor(拦截器)**
+
+ + 是一个标记接口,表示通用的拦截器类型,通常用于包装方法调用。
+
+6. **IntroductionInterceptor(引介拦截器)**
+
+ + 实现该接口的类可以在目标对象上添加新的方法和属性,用于实现AOP引介功能。
+
+7. **MethodBeforeAdvice(方法前置通知)**
+
+ + 用于在目标方法执行前执行自定义逻辑。
+
+8. **MethodInterceptor(方法拦截器)**
+
+ + 实现该接口的类可以在目标方法执行前、执行后以及抛出异常时进行拦截,并执行自定义的逻辑。
+
+9. **ThrowsAdvice(异常通知)**
+
+ + 用于在目标方法抛出异常时执行自定义逻辑。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advice {
+<>
+
+}
+class AfterAdvice {
+<>
+
+}
+class AfterReturningAdvice {
+<>
+
+}
+class BeforeAdvice {
+<>
+
+}
+class ConstructorInterceptor {
+<>
+
+}
+class Interceptor {
+<>
+
+}
+class IntroductionInterceptor {
+<>
+
+}
+class MethodBeforeAdvice {
+<>
+
+}
+class MethodInterceptor {
+<>
+
+}
+class ThrowsAdvice {
+<>
+
+}
+
+AfterAdvice --> Advice
+AfterReturningAdvice --> AfterAdvice
+BeforeAdvice --> Advice
+ConstructorInterceptor --> Interceptor
+Interceptor --> Advice
+IntroductionInterceptor --> Advice
+IntroductionInterceptor --> MethodInterceptor
+MethodBeforeAdvice --> BeforeAdvice
+MethodInterceptor --> Interceptor
+ThrowsAdvice --> AfterAdvice
+
+~~~
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advice/pom.xml b/spring-aop/spring-aop-advice/pom.xml
new file mode 100644
index 00000000..1b57f0f8
--- /dev/null
+++ b/spring-aop/spring-aop-advice/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advice
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advised/README.md b/spring-aop/spring-aop-advised/README.md
new file mode 100644
index 00000000..4d2f7146
--- /dev/null
+++ b/spring-aop/spring-aop-advised/README.md
@@ -0,0 +1,324 @@
+## Advised
+
+- [Advised](#advised)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`Advised` 接口是 Spring AOP 中的核心接口之一,代表了被 Spring AOP 支持的被通知对象,它提供了对被通知对象的通用管理方法,包括检查是否被冻结、是否代理目标类、获取被代理接口、添加、移除和获取通知等,通过这些方法可以实现对被通知对象的动态通知管理。
+
+### 三、主要功能
+
+1. **冻结状态检查(isFrozen)**
+
+ + 可以检查被通知对象是否处于冻结状态,即是否可以修改其 AOP 配置。
+
+2. **代理类型检查(isProxyTargetClass)**
+
+ + 可以检查是否代理了目标类,而不是目标接口。
+
+3. **获取被代理接口(getProxiedInterfaces)**
+
+ + 可以获取被代理对象所实现的接口数组。
+
+4. **接口代理检查(isInterfaceProxied)**
+
+ + 可以检查给定的接口是否被代理。
+
+5. **添加通知(addAdvice)**
+
+ + 可以向被通知对象添加通知,实现对目标方法的增强。
+
+6. **指定位置添加通知(addAdvice)**
+
+ + 可以在指定位置添加通知,控制通知的执行顺序。
+
+7. **获取所有通知(getAdvices)**
+
+ + 可以获取所有添加到被通知对象的通知。
+
+8. **移除通知(removeAdvice)**
+
+ + 可以移除指定的通知,动态调整通知的配置。
+
+### 四、接口源码
+
+`Advised`接口 ,规定了代理工厂配置的结构和行为。这个接口包含了许多方法,用于管理AOP代理的配置,包括拦截器、通知器、被代理的接口等。通过这个接口,可以获取和操作AOP代理的配置信息,如是否冻结、是否代理目标类、获取被代理的接口、添加和移除通知器等。
+
+```java
+/**
+ * 用于实现持有 AOP 代理工厂配置的类的接口。该配置包括拦截器和其他通知器、通知器以及被代理的接口。
+ *
+ * 从 Spring 获取的任何 AOP 代理都可以转换为此接口,以允许对其 AOP 通知进行操作。
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @since 13.03.2003
+ * @see org.springframework.aop.framework.AdvisedSupport
+ */
+public interface Advised extends TargetClassAware {
+
+ /**
+ * 返回 Advised 配置是否已冻结,如果已冻结,则无法进行通知更改。
+ */
+ boolean isFrozen();
+
+ /**
+ * 是否代理了完整的目标类,而不是指定的接口?
+ */
+ boolean isProxyTargetClass();
+
+ /**
+ * 返回 AOP 代理所代理的接口。
+ * 不会包括目标类,目标类可能也会被代理。
+ */
+ Class>[] getProxiedInterfaces();
+
+ /**
+ * 确定给定的接口是否被代理。
+ * @param intf 要检查的接口
+ */
+ boolean isInterfaceProxied(Class> intf);
+
+ /**
+ * 更改此 Advised 对象使用的 TargetSource。
+ * 仅在配置未被冻结时有效。
+ * @param targetSource 要使用的新 TargetSource
+ */
+ void setTargetSource(TargetSource targetSource);
+
+ /**
+ * 返回此 Advised 对象使用的 TargetSource。
+ */
+ TargetSource getTargetSource();
+
+ /**
+ * 设置代理是否应该被 AOP 框架公开为 {@link ThreadLocal},以便通过 {@link AopContext} 类进行检索。
+ * 如果需要在通知对象上调用自身的方法并应用通知,则可能需要公开代理。否则,如果通知对象调用 {@code this} 的方法,将不会应用任何通知。
+ * 默认为 {@code false},以获得最佳性能。
+ */
+ void setExposeProxy(boolean exposeProxy);
+
+ /**
+ * 返回工厂是否应将代理公开为 {@link ThreadLocal}。
+ * 如果需要在通知对象上调用自身的方法并应用通知,则可能需要公开代理。否则,如果通知对象调用 {@code this} 的方法,将不会应用任何通知。
+ * 获取代理类似于 EJB 调用 {@code getEJBObject()}。
+ * @see AopContext
+ */
+ boolean isExposeProxy();
+
+ /**
+ * 设置此代理配置是否经过预过滤,以便仅包含适用的通知器(与此代理的目标类匹配)。
+ * 默认为 "false"。如果通知器已经被预过滤,即可以跳过构建实际的代理调用链时的 ClassFilter 检查,则将其设置为 "true"。
+ * @see org.springframework.aop.ClassFilter
+ */
+ void setPreFiltered(boolean preFiltered);
+
+ /**
+ * 返回此代理配置是否经过预过滤,以便仅包含适用的通知器(与此代理的目标类匹配)。
+ */
+ boolean isPreFiltered();
+
+ /**
+ * 返回应用于此代理的通知器。
+ * @return 应用于此代理的通知器列表(永远不会为 {@code null})
+ */
+ Advisor[] getAdvisors();
+
+ /**
+ * 返回应用于此代理的通知器数量。
+ * 默认实现委托给 {@code getAdvisors().length}。
+ * @since 5.3.1
+ */
+ default int getAdvisorCount() {
+ return getAdvisors().length;
+ }
+
+ /**
+ * 在通知器链的末尾添加一个通知器。
+ * 通知器可以是 {@link org.springframework.aop.IntroductionAdvisor},
+ * 在从相关工厂下次获取代理时将提供新的接口。
+ * @param advisor 要添加到链的末尾的通知器
+ * @throws AopConfigException 如果通知器无效
+ */
+ void addAdvisor(Advisor advisor) throws AopConfigException;
+
+ /**
+ * 在链中的指定位置添加一个通知器。
+ * @param advisor 要在链中指定位置添加的通知器
+ * @param pos 链中的位置(0 是头)。必须有效。
+ * @throws AopConfigException 如果通知器无效
+ */
+ void addAdvisor(int pos, Advisor advisor) throws AopConfigException;
+
+ /**
+ * 删除给定的通知器。
+ * @param advisor 要移除的通知器
+ * @return 如果已移除通知器,则返回 {@code true};如果未找到该通知器,因此无法移除,则返回 {@code false}
+ */
+ boolean removeAdvisor(Advisor advisor);
+
+ /**
+ * 移除给定索引处的通知器。
+ * @param index 要移除的通知器的索引
+ * @throws AopConfigException 如果索引无效
+ */
+ void removeAdvisor(int index) throws AopConfigException;
+
+ /**
+ * 返回给定通知器的索引(从 0 开始),
+ * 如果没有这样的通知器适用于此代理,则返回 -1。
+ * 此方法的返回值可用于索引到通知器数组中。
+ * @param advisor 要搜索的通知器
+ * @return 此通知器的从 0 开始的索引,如果没有这样的通知器,则返回 -1
+ */
+ int indexOf(Advisor advisor);
+
+ /**
+ * 替换给定的通知器。
+ * 注意如果通知器是 {@link org.springframework.aop.IntroductionAdvisor},
+ * 并且替换项不是或实现了不同的接口,则需要重新获取代理,否则旧接口将不被支持,新接口也将不被实现。
+ * @param a 要替换的通知器
+ * @param b 要替换的新通知器
+ * @return 是否已替换。如果通知器未在通知器列表中找到,则此方法返回 {@code false},并且不执行任何操作。
+ * @throws AopConfigException 如果通知器无效
+ */
+ boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;
+
+ /**
+ * 将给定的 AOP Alliance 通知添加到通知(拦截器)链的末尾。
+ * 这将被包装在一个始终适用的 DefaultPointcutAdvisor 中,并从 {@code getAdvisors()} 方法以此包装形式返回。
+ * 请注意,给定的通知将应用于代理的所有调用,甚至是 {@code toString()} 方法!使用适当的通知实现或指定适当的切入点以适用于更窄范围的方法。
+ * @param advice 要添加到链末尾的通知
+ * @throws AopConfigException 如果通知无效
+ * @see #addAdvice(int, Advice)
+ * @see org.springframework.aop.support.DefaultPointcutAdvisor
+ */
+ void addAdvice(Advice advice) throws AopConfigException;
+
+ /**
+ * 将给定的 AOP Alliance 通知添加到通知链的指定位置。
+ * 这将被包装在一个 {@link org.springframework.aop.support.DefaultPointcutAdvisor} 中,
+ * 并以此包装形式从 {@link #getAdvisors()} 方法返回。
+ * 注意给定的通知将应用于代理的所有调用,甚至是 {@code toString()} 方法!使用适当的通知实现或指定适当的切入点以适用于更窄范围的方法。
+ * @param pos 从 0 开始的索引(头部)
+ * @param advice 要在通知链的指定位置添加的通知
+ * @throws AopConfigException 如果通知无效
+ */
+ void addAdvice(int pos, Advice advice) throws AopConfigException;
+
+ /**
+ * 移除包含给定通知的通知器。
+ * @param advice 要移除的通知
+ * @return 如果找到并移除了通知,则返回 {@code true};如果没有找到该通知,则返回 {@code false}
+ */
+ boolean removeAdvice(Advice advice);
+
+ /**
+ * 返回给定 AOP Alliance 通知的索引(从 0 开始),
+ * 如果没有这样的通知是此代理的通知,则返回 -1。
+ * 此方法的返回值可用于索引到通知器数组中。
+ * @param advice 要搜索的 AOP Alliance 通知
+ * @return 此通知的从 0 开始的索引,如果没有这样的通知,则返回 -1
+ */
+ int indexOf(Advice advice);
+
+ /**
+ * 由于通常将 {@code toString()} 委托给目标,因此此方法返回 AOP 代理的等效描述。
+ * @return 代理配置的字符串描述
+ */
+ String toProxyConfigString();
+
+}
+```
+
+### 五、主要实现
+
++ **AdvisedSupport**
+
+ + 负责管理 AOP 代理配置信息的核心类,它包含了通知器、目标对象、目标源等关键属性,能够灵活地配置和管理 AOP 代理的创建过程,并提供了各种方法来处理代理配置的冻结状态、代理暴露等功能。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advised {
+<>
+
+}
+class AdvisedSupport
+class TargetClassAware {
+<>
+
+}
+
+Advised --> TargetClassAware
+AdvisedSupport ..> Advised
+~~~
+
+### 七、最佳实践
+
+使用 `AdvisedSupport` 类来配置代理对象的相关属性,包括设置目标对象、接口、通知、通知器、是否暴露代理对象、是否使用 CGLIB 代理以及冻结对象,并通过 `toProxyConfigString()` 方法打印代理配置信息。
+
+```java
+public class AdvisedDemo {
+
+ public static void main(String[] args) {
+ // 创建 AdvisedSupport 对象
+ AdvisedSupport advisedSupport = new AdvisedSupport();
+ // 设置目标对象
+ advisedSupport.setTarget(new MyServiceImpl());
+ // 设置目标对象实现的接口
+ advisedSupport.setInterfaces(MyService.class);
+ // 添加通知
+ advisedSupport.addAdvice(new Advice() {});
+ // 添加通知器
+ advisedSupport.addAdvisor(new DefaultPointcutAdvisor());
+ // 暴露代理对象
+ advisedSupport.setExposeProxy(true);
+ // 设置CGLIB 代理
+ advisedSupport.setProxyTargetClass(true);
+ // 冻结对象
+ advisedSupport.setFrozen(true);
+ // 打印
+ System.out.println("AdvisedSupport = " + advisedSupport.toProxyConfigString());
+ }
+}
+```
+
+定义了一个 `MyService` 接口
+
+```java
+public interface MyService {
+ void foo();
+}
+```
+
+实现了 `MyService` 接口的 `MyServiceImpl` 类。
+
+```java
+public class MyServiceImpl implements MyService {
+
+ @Override
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
+```
+
+运行结果,显示了 `AdvisedSupport` 对象的配置信息,包括代理的接口、通知器、目标对象信息、代理类型以及其他相关设置。
+
+```java
+AdvisedSupport = org.springframework.aop.framework.AdvisedSupport: 1 interfaces [com.xcs.spring.MyService]; 2 advisors [org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [com.xcs.spring.AdvisedDemo$1@32d992b2], org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [org.springframework.aop.Advisor$1@215be6bb]]; targetSource [SingletonTargetSource for target object [com.xcs.spring.MyServiceImpl@5d5eef3d]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=true; frozen=true
+```
diff --git a/spring-aop/spring-aop-advised/pom.xml b/spring-aop/spring-aop-advised/pom.xml
new file mode 100644
index 00000000..bec9e499
--- /dev/null
+++ b/spring-aop/spring-aop-advised/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-advised
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/AdvisedDemo.java b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/AdvisedDemo.java
new file mode 100644
index 00000000..c89390a7
--- /dev/null
+++ b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/AdvisedDemo.java
@@ -0,0 +1,29 @@
+package com.xcs.spring;
+
+import org.aopalliance.aop.Advice;
+import org.springframework.aop.framework.AdvisedSupport;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+
+public class AdvisedDemo {
+
+ public static void main(String[] args) {
+ // 创建 AdvisedSupport 对象
+ AdvisedSupport advisedSupport = new AdvisedSupport();
+ // 设置目标对象
+ advisedSupport.setTarget(new MyServiceImpl());
+ // 设置目标对象实现的接口
+ advisedSupport.setInterfaces(MyService.class);
+ // 添加通知
+ advisedSupport.addAdvice(new Advice() {});
+ // 添加通知器
+ advisedSupport.addAdvisor(new DefaultPointcutAdvisor());
+ // 暴露代理对象
+ advisedSupport.setExposeProxy(true);
+ // 设置CGLIB 代理
+ advisedSupport.setProxyTargetClass(true);
+ // 冻结对象
+ advisedSupport.setFrozen(true);
+ // 打印
+ System.out.println("AdvisedSupport = " + advisedSupport.toProxyConfigString());
+ }
+}
diff --git a/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..8a38ece2
--- /dev/null
+++ b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,5 @@
+package com.xcs.spring;
+
+public interface MyService {
+ void foo();
+}
diff --git a/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyServiceImpl.java b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyServiceImpl.java
new file mode 100644
index 00000000..3b9e3784
--- /dev/null
+++ b/spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyServiceImpl.java
@@ -0,0 +1,9 @@
+package com.xcs.spring;
+
+public class MyServiceImpl implements MyService {
+
+ @Override
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
diff --git a/spring-aop/spring-aop-advisor/README.md b/spring-aop/spring-aop-advisor/README.md
index 5509a0b9..afdb573e 100644
--- a/spring-aop/spring-aop-advisor/README.md
+++ b/spring-aop/spring-aop-advisor/README.md
@@ -1,32 +1,238 @@
## Advisor
-- [Advisor](#Advisor)
- - [一、基本信息](#一基本信息)
- - [二、知识储备](#二知识储备)
- - [三、基本描述](#三基本描述)
- - [四、主要功能](#四主要功能)
- - [五、接口源码](#五接口源码)
- - [六、主要实现](#六主要实现)
- - [七、最佳实践](#七最佳实践)
- - [八、与其他组件的关系](#八与其他组件的关系)
- - [九、常见问题](#九常见问题)
+- [Advisor](#advisor)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
### 一、基本信息
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
-### 二、知识储备
+### 二、基本描述
-### 三、基本描述
+`Advisor`接口是Spring框架中的一个关键接口,用于将切点(Pointcut)和通知(Advice)组合起来,以便在AOP(面向切面编程)中定义何时、何地以及如何应用横切关注点。
-### 四、主要功能
+### 三、主要功能
-### 五、接口源码
+1. **组合切点和通知**
-### 六、主要实现
+ + Advisor接口允许将切点(Pointcut)和通知(Advice)组合在一起。切点确定何时应该应用通知,而通知定义了在连接点处执行的代码。
+
+
+### 四、接口源码
+
+`Advisor`接口是Spring框架中的一个基础接口,用于持有AOP通知(在连接点执行的操作)和确定通知适用性的过滤器(例如切点)。该接口定义了获取通知部分的方法`getAdvice()`,以及确定通知是否与特定实例相关联的方法`isPerInstance()`。同时,该接口还提供了一个常量`EMPTY_ADVICE`,用作当未配置适当通知时的占位符。在Spring AOP中,Advisor接口允许支持不同类型的通知,例如拦截器、前置通知、异常通知等,并且并非所有通知都需要使用拦截来实现。
+
+```java
+/**
+ * 基础接口,持有AOP 通知(在连接点执行的操作)和确定通知适用性的过滤器(例如切点)。
+ * 此接口不供Spring用户使用,而是为了在支持不同类型的通知时提供共性。
+ *
+ * Spring AOP基于通过方法拦截(interception)提供的环绕通知,符合AOP Alliance拦截API。
+ * Advisor接口允许支持不同类型的通知,例如前置和后置通知,它们不一定要使用拦截来实现。
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ */
+public interface Advisor {
+
+ /**
+ * 如果尚未配置适当的通知,则从{@link #getAdvice()}返回一个空的{@code Advice}的常用占位符。
+ * @since 5.0
+ */
+ Advice EMPTY_ADVICE = new Advice() {};
+
+
+ /**
+ * 返回此方面的通知部分。通知可以是拦截器、前置通知、异常通知等。
+ * @return 如果切点匹配,则应应用的通知
+ * @see org.aopalliance.intercept.MethodInterceptor
+ * @see BeforeAdvice
+ * @see ThrowsAdvice
+ * @see AfterReturningAdvice
+ */
+ Advice getAdvice();
+
+ /**
+ * 返回此通知是否与特定实例相关联(例如,创建混入),或与从同一Spring bean工厂获取的被通知类的所有实例共享。
+ *
请注意,框架当前不使用此方法。
+ * 典型的Advisor实现总是返回{@code true}。
+ * 使用singleton/prototype bean定义或适当的编程代理创建来确保Advisor具有正确的生命周期模型。
+ * @return 此通知是否与特定目标实例关联
+ */
+ boolean isPerInstance();
+
+}
+```
+
+`PointcutAdvisor`接口是所有由切点驱动的Advisor的超级接口。它覆盖了几乎所有的Advisor,但不包括引介Advisor,因为引介Advisor不适用于方法级别的匹配。该接口表示由切点驱动的Advisor,通过`getPointcut()`方法获取驱动该Advisor的切点。 PointcutAdvisor通常用于基于切点的切面,通过指定切点来确定通知逻辑应该应用于哪些连接点。
+
+```java
+/**
+ * 所有由切点驱动的Advisor的超级接口。
+ * 这几乎涵盖了所有的Advisor,除了引介Advisor,
+ * 因为方法级别的匹配不适用于引介Advisor。
+ *
+ * 该接口是Advisor的子接口,用于表示由切点驱动的Advisor。
+ * 切点驱动的Advisor通常用于基于切点的切面,通过指定切点来确定通知逻辑应该应用于哪些连接点。
+ *
+ * 作者:Rod Johnson
+ */
+public interface PointcutAdvisor extends Advisor {
+
+ /**
+ * 获取驱动该Advisor的切点。
+ */
+ Pointcut getPointcut();
+
+}
+```
+
+### 五、主要实现
+
+1. **RegexpMethodPointcutAdvisor**
+
+ - 基于正则表达式来匹配方法名的切点。通过使用正则表达式,可以根据方法名模式匹配连接点,并将通知应用于匹配的连接点,从而实现基于方法名模式的切面逻辑。
+2. **AspectJExpressionPointcutAdvisor**
+
+ - 基于AspectJ表达式来定义切点。通过使用AspectJ的语法,可以更灵活地定义切面,从而匹配连接点,并将通知应用于匹配的连接点,实现更复杂的切面逻辑。
+3. **NameMatchMethodPointcutAdvisor**
+
+ - 基于方法名模式匹配来定义切点。通过使用方法名模式,可以轻松地匹配连接点,并将通知应用于匹配的连接点,从而实现基于方法名模式的切面逻辑。
+4. **DefaultPointcutAdvisor**
+
+ - 一个通用的切点Advisor,用于将切点和通知组合在一起。它允许将任何类型的通知与任何类型的切点结合使用,并将通知应用于匹配的连接点,从而实现横切关注点的管理。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class Advisor {
+<>
+
+}
+class AspectJPointcutAdvisor
+class DefaultPointcutAdvisor
+class NameMatchMethodPointcutAdvisor
+class PointcutAdvisor {
+<>
+
+}
+class RegexpMethodPointcutAdvisor
+
+AspectJPointcutAdvisor ..> PointcutAdvisor
+DefaultPointcutAdvisor ..> PointcutAdvisor
+NameMatchMethodPointcutAdvisor ..> PointcutAdvisor
+PointcutAdvisor --> Advisor
+RegexpMethodPointcutAdvisor ..> PointcutAdvisor
+
+~~~
### 七、最佳实践
-### 八、与其他组件的关系
+使用Advisor来创建代理对象并应用切面逻辑。首先,通过创建代理工厂`ProxyFactory`,并将目标对象`MyService`传递给它。然后,通过`proxyFactory.addAdvisor(new MyCustomAdvisor())`添加了一个自定义的Advisor,其中包含了切点和通知的定义。接着,通过`proxyFactory.getProxy()`获取了代理对象`MyService`。最后,调用了代理对象的`foo()`方法,该方法触发了切面逻辑的执行。
+
+```java
+public class AdvisorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 添加Advisor
+ proxyFactory.addAdvisor(new MyCustomAdvisor());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用方法
+ proxy.foo();
+ }
+}
+```
+
+`MyCustomAdvisor`类是一个自定义的Advisor,它实现了`PointcutAdvisor`接口,并用于将通知应用于带有特定注解的方法。在该类中,我们定义了一个通知对象`advice`和一个切点对象`pointcut`,切点用于匹配带有自定义注解`MyCustomAnnotation`的方法。通过实现`getPointcut()`方法和`getAdvice()`方法,我们指定了切点和通知的逻辑。
+
+```java
+
+/**
+ * 自定义Advisor,用于将通知应用于带有特定注解的方法。
+ */
+public class MyCustomAdvisor implements PointcutAdvisor {
+
+ /**
+ * 通知对象
+ */
+ private final Advice advice = new MyAdvice();
+
+ /**
+ * 切点对象,用于匹配带有自定义注解的方法
+ */
+ private final Pointcut pointcut = new AnnotationMatchingPointcut(null, MyCustomAnnotation.class);
+
+ @Override
+ public Pointcut getPointcut() {
+ return pointcut;
+ }
+
+ @Override
+ public Advice getAdvice() {
+ return advice;
+ }
+
+ @Override
+ public boolean isPerInstance() {
+ return true;
+ }
+}
+```
+
+`MyAdvice`类是一个通知类,它实现了`MethodInterceptor`接口,用于在方法执行前后添加额外的逻辑。在`invoke`方法中,我们首先输出了正在调用的方法名,然后调用了`invocation.proceed()`方法来执行原始方法,并获取了方法执行的结果。最后,我们在方法执行之后再次输出了方法名。
+
+```java
+public class MyAdvice implements MethodInterceptor {
+
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ // 在方法调用之前执行的逻辑
+ System.out.println("Before Method " + invocation.getMethod().getName());
+ // 调用原始方法
+ Object result = invocation.proceed();
+ // 在方法调用之后执行的逻辑
+ System.out.println("After Method " + invocation.getMethod().getName());
+ return result;
+ }
+}
+```
+
+`MyCustomAnnotation`是一个自定义的注解,通常用于标记需要特殊处理的方法。
+
+```java
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface MyCustomAnnotation {
+}
+```
+
+`MyCustomAnnotation`类其中包含一个名为`foo`的方法。该方法被`@MyCustomAnnotation`注解标记,表明需要特殊处理。
+
+```java
+public class MyService {
+
+ @MyCustomAnnotation
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
+```
+
+运行结果,切面逻辑成功应用于带有特定注解的方法。
-### 九、常见问题
\ No newline at end of file
+```java
+Before Method foo
+foo...
+After Method foo
+```
diff --git a/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/AdvisorDemo.java b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/AdvisorDemo.java
new file mode 100644
index 00000000..bf3117da
--- /dev/null
+++ b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/AdvisorDemo.java
@@ -0,0 +1,17 @@
+package com.xcs.spring;
+
+import org.springframework.aop.framework.ProxyFactory;
+
+public class AdvisorDemo {
+
+ public static void main(String[] args) {
+ // 创建代理工厂
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 添加Advisor
+ proxyFactory.addAdvisor(new MyCustomAdvisor());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 调用方法
+ proxy.foo();
+ }
+}
diff --git a/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyAdvice.java b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyAdvice.java
new file mode 100644
index 00000000..e731cfe4
--- /dev/null
+++ b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyAdvice.java
@@ -0,0 +1,18 @@
+package com.xcs.spring;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+public class MyAdvice implements MethodInterceptor {
+
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ // 在方法调用之前执行的逻辑
+ System.out.println("Before Method " + invocation.getMethod().getName());
+ // 调用原始方法
+ Object result = invocation.proceed();
+ // 在方法调用之后执行的逻辑
+ System.out.println("After Method " + invocation.getMethod().getName());
+ return result;
+ }
+}
diff --git a/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAdvisor.java b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAdvisor.java
new file mode 100644
index 00000000..1d2f9e2d
--- /dev/null
+++ b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAdvisor.java
@@ -0,0 +1,37 @@
+package com.xcs.spring;
+
+import org.aopalliance.aop.Advice;
+import org.springframework.aop.Pointcut;
+import org.springframework.aop.PointcutAdvisor;
+import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
+
+/**
+ * 自定义Advisor,用于将通知应用于带有特定注解的方法。
+ */
+public class MyCustomAdvisor implements PointcutAdvisor {
+
+ /**
+ * 通知对象
+ */
+ private final Advice advice = new MyAdvice();
+
+ /**
+ * 切点对象,用于匹配带有自定义注解的方法
+ */
+ private final Pointcut pointcut = new AnnotationMatchingPointcut(null, MyCustomAnnotation.class);
+
+ @Override
+ public Pointcut getPointcut() {
+ return pointcut;
+ }
+
+ @Override
+ public Advice getAdvice() {
+ return advice;
+ }
+
+ @Override
+ public boolean isPerInstance() {
+ return true;
+ }
+}
diff --git a/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAnnotation.java b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAnnotation.java
new file mode 100644
index 00000000..b93edc62
--- /dev/null
+++ b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAnnotation.java
@@ -0,0 +1,14 @@
+package com.xcs.spring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 自定义注解
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface MyCustomAnnotation {
+}
diff --git a/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyService.java
new file mode 100644
index 00000000..0792be31
--- /dev/null
+++ b/spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyService.java
@@ -0,0 +1,9 @@
+package com.xcs.spring;
+
+public class MyService {
+
+ @MyCustomAnnotation
+ public void foo() {
+ System.out.println("foo...");
+ }
+}
diff --git a/spring-aop/spring-aop-advisorAdapter/README.md b/spring-aop/spring-aop-advisorAdapter/README.md
new file mode 100644
index 00000000..f2dacc36
--- /dev/null
+++ b/spring-aop/spring-aop-advisorAdapter/README.md
@@ -0,0 +1,462 @@
+## AdvisorAdapter
+
+- [AdvisorAdapter](#advisoradapter)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、接口源码](#四接口源码)
+ - [五、主要实现](#五主要实现)
+ - [六、类关系图](#六类关系图)
+ - [七、最佳实践](#七最佳实践)
+ - [八、源码分析](#八源码分析)
+
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`AdvisorAdapter` 接口是 Spring AOP 中的一个重要接口,用于将不同类型的通知(Advice)适配到拦截器链中,以便将其应用于目标方法的执行。它允许我们自定义适配器来将自定义的通知与 Spring AOP 框架结合,从而实现对目标方法的前置、后置、环绕等类型的增强操作,为 AOP 的灵活性和可扩展性提供了支持。
+
+### 三、主要功能
+
+1. **通知适配**
+
+ + 将不同类型的通知(Advice)适配到 Spring AOP 拦截器链中,以便将其应用于目标方法的执行。
+
+2. **支持不同通知类型**
+
+ + 支持适配各种类型的通知,包括前置通知(MethodBeforeAdvice)、后置通知(AfterReturningAdvice)、环绕通知(MethodInterceptor)、抛出异常通知(ThrowsAdvice)等。
+
+3. **适配器注册和管理**
+
+ + 允许我们注册和管理不同类型通知的适配器,以便在应用中使用不同类型的通知。
+
+
+### 四、接口源码
+
+这个接口定义了一种机制,允许向 Spring AOP 框架中引入新的 Advisor 和 Advice 类型。实现该接口的对象可以将自定义的 Advice 类型转换为 AOP Alliance 拦截器,使得这些自定义的 Advice 类型能够在 Spring AOP 框架中被使用。通常情况下,大多数 Spring 用户不需要直接实现这个接口;只有在需要引入新的 Advisor 或 Advice 类型时才需要这样做。
+
+```java
+/**
+ * 允许扩展 Spring AOP 框架的接口,以处理新的 Advisor 和 Advice 类型。
+ *
+ * 实现该接口的对象可以从自定义的 Advice 类型创建 AOP Alliance 拦截器,
+ * 从而使得这些 Advice 类型可以在 Spring AOP 框架中使用,该框架在底层使用拦截。
+ *
+ *
大多数 Spring 用户无需实现此接口;只有在需要向 Spring 引入更多的 Advisor 或 Advice 类型时才需要这样做。
+ *
+ * @author Rod Johnson
+ */
+public interface AdvisorAdapter {
+
+ /**
+ * 此适配器是否了解该通知对象?是否可以使用 Advisor 包含此通知作为参数调用 getInterceptors 方法?
+ * @param advice 一个 Advice,如 BeforeAdvice
+ * @return 此适配器是否了解给定的 Advice 对象
+ * @see #getInterceptor(org.springframework.aop.Advisor)
+ * @see org.springframework.aop.BeforeAdvice
+ */
+ boolean supportsAdvice(Advice advice);
+
+ /**
+ * 返回一个 AOP Alliance MethodInterceptor,将给定 Advice 的行为暴露给基于拦截的 AOP 框架。
+ *
不必担心 Advisor 中包含的 Pointcut;AOP 框架将负责检查切点。
+ * @param advisor Advisor。supportsAdvice() 方法必须在此对象上返回 true
+ * @return 此 Advisor 的 AOP Alliance 拦截器。无需为效率缓存实例,因为 AOP 框架会缓存 Advice 链。
+ */
+ MethodInterceptor getInterceptor(Advisor advisor);
+}
+```
+
+### 五、主要实现
+
+1. **MethodBeforeAdviceAdapter**
+
+ + 用于将 `MethodBeforeAdvice` 类型的通知适配到 Spring AOP 拦截器链中。`MethodBeforeAdvice` 是一个在目标方法执行前执行的通知接口。
+
+2. **ThrowsAdviceAdapter**
+
+ + 用于将 `ThrowsAdvice` 类型的通知适配到 Spring AOP 拦截器链中。`ThrowsAdvice` 通知用于捕获目标方法抛出的异常。
+
+3. **AfterReturningAdviceAdapter**
+
+ + 用于将 `AfterReturningAdvice` 类型的通知适配到 Spring AOP 拦截器链中。`AfterReturningAdvice` 通知在目标方法正常返回后执行。
+
+### 六、类关系图
+
+~~~mermaid
+classDiagram
+direction BT
+class AdvisorAdapter {
+<>
+
+}
+class AfterReturningAdviceAdapter
+class MethodBeforeAdviceAdapter
+class ThrowsAdviceAdapter
+
+AfterReturningAdviceAdapter ..> AdvisorAdapter
+MethodBeforeAdviceAdapter ..> AdvisorAdapter
+ThrowsAdviceAdapter ..> AdvisorAdapter
+~~~
+
+### 七、最佳实践
+
+用自定义的 AdvisorAdapter 和 Advice 来实现对目标方法的增强。在示例中,首先注册了一个自定义的 AdvisorAdapter(NullReturningAdviceAdapter),然后创建了一个代理工厂(ProxyFactory)并向其添加了一个自定义的通知(MyNullReturningAdvice)。最后,通过代理工厂获取了代理对象,并调用了两个方法,其中一个方法会触发通知,另一个方法不会触发通知。
+
+```java
+public class AdvisorAdapterDemo {
+
+ public static void main(String[] args) {
+ // 注册自定义适配器
+ GlobalAdvisorAdapterRegistry.getInstance().registerAdvisorAdapter(new NullReturningAdviceAdapter());
+ // 创建代理工厂
+ ProxyFactory proxyFactory = new ProxyFactory(new MyService());
+ // 添加Advisor
+ proxyFactory.addAdvice(new MyNullReturningAdvice());
+ // 获取代理对象
+ MyService proxy = (MyService) proxyFactory.getProxy();
+ // 不会触发通知
+ System.out.println("foo return value : " + proxy.foo());
+ // 换行
+ System.out.println("==================================");
+ // 会触发通知
+ System.out.println("bar return value : " + proxy.bar());
+ }
+}
+```
+
+一个空返回通知的适配器,用于将空返回通知(NullReturningAdvice)适配到拦截器链中。它实现了 AdvisorAdapter 接口,包含了支持给定通知和获取方法拦截器的功能,以便将特定类型的通知行为暴露给基于拦截的 AOP 框架。
+
+```java
+/**
+ * 空返回通知适配器,用于将空返回通知(NullReturningAdvice)适配到拦截器链中。
+ */
+public class NullReturningAdviceAdapter implements AdvisorAdapter {
+
+ /**
+ * 判断该适配器是否支持给定的通知。
+ * @param advice 一个通知,如空返回通知(NullReturningAdvice)
+ * @return 如果该适配器支持给定的通知,则返回 true;否则返回 false
+ */
+ @Override
+ public boolean supportsAdvice(Advice advice) {
+ return (advice instanceof NullReturningAdvice);
+ }
+
+ /**
+ * 获取一个方法拦截器,将给定的通知行为暴露给基于拦截的 AOP 框架。
+ * @param advisor Advisor。supportsAdvice() 方法必须在此对象上返回 true
+ * @return 给定 Advisor 的方法拦截器
+ */
+ @Override
+ public MethodInterceptor getInterceptor(Advisor advisor) {
+ NullReturningAdvice advice = (NullReturningAdvice) advisor.getAdvice();
+ return new NullReturningAdviceInterceptor(advice);
+ }
+}
+```
+
+一个空返回通知拦截器,用于在方法执行后检查返回值是否为空,并根据情况执行空返回通知的逻辑。它实现了 MethodInterceptor 和 AfterAdvice 接口,通过拦截方法调用后的返回值来判断是否需要执行空返回通知,并在必要时调用空返回通知的逻辑。
+
+```java
+/**
+ * 空返回通知拦截器,用于在方法执行后检查返回值是否为空,并根据情况执行空返回通知的逻辑。
+ */
+public class NullReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice {
+
+ /** 空返回通知 */
+ private final NullReturningAdvice advice;
+
+ /**
+ * 构造一个空返回通知拦截器。
+ * @param advice 空返回通知
+ */
+ public NullReturningAdviceInterceptor(NullReturningAdvice advice) {
+ Assert.notNull(advice, "Advice must not be null");
+ this.advice = advice;
+ }
+
+ /**
+ * 在方法执行后拦截,检查返回值是否为空,并根据情况执行空返回通知的逻辑。
+ * @param mi 方法调用信息
+ * @return 方法执行结果,如果返回值为空,则根据空返回通知执行后的返回值
+ * @throws Throwable 如果方法调用过程中发生异常,则抛出异常
+ */
+ @Override
+ public Object invoke(MethodInvocation mi) throws Throwable {
+ // 执行方法调用,获取返回值
+ Object retVal = mi.proceed();
+ // 如果返回值为空,则根据空返回通知执行后的返回值
+ if (retVal == null) {
+ retVal = this.advice.nullReturning(mi.getMethod(), mi.getArguments(), mi.getThis());
+ }
+ return retVal;
+ }
+}
+```
+
+一个空返回通知的定义,继承了 AfterAdvice 接口。它包含了一个方法 nullReturning,用于在目标方法返回值为空时执行相应的逻辑,并返回一个新的返回值。
+
+```java
+/**
+ * 空返回通知接口,继承自 AfterAdvice。
+ */
+public interface NullReturningAdvice extends AfterAdvice {
+
+ /**
+ * 当目标方法返回值为空时调用的方法。
+ * @param method 目标方法
+ * @param args 方法参数
+ * @param target 目标对象
+ * @return 空返回通知执行后的返回值
+ * @throws Throwable 如果在执行空返回通知的过程中发生异常,则抛出异常
+ */
+ Object nullReturning(Method method, Object[] args, @Nullable Object target) throws Throwable;
+}
+
+```
+
+实现了`NullReturningAdvice`空返回通知接口,用于在目标方法返回值为空时执行特定逻辑。在 nullReturning 方法中返回一个默认的字符串值。
+
+```java
+public class MyNullReturningAdvice implements NullReturningAdvice {
+
+ @Override
+ public Object nullReturning(Method method, Object[] args, Object target) throws Throwable {
+ return "this is a defaultValue";
+ }
+}
+```
+
+简单的服务类,包含了两个方法 foo 和 bar。foo 方法执行后返回字符串 "this is a foo",而 bar 方法执行后返回 null。
+
+```java
+public class MyService {
+
+ public String foo() {
+ System.out.println("foo...");
+ return "this is a foo";
+ }
+
+ public String bar() {
+ System.out.println("bar...");
+ return null;
+ }
+}
+```
+
+运行结果,调用了 foo 方法,它返回 "this is a foo";然后调用了 bar 方法,由于其返回值为 null,因此触发了空返回通知,打印了相应的消息,并返回了默认值 "this is a defaultValue"。
+
+```java
+foo...
+foo return value : this is a foo
+==================================
+bar...
+bar return value : this is a defaultValue
+```
+
+### 八、源码分析
+
+**注册适配器**
+
+在`org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#registerAdvisorAdapter`方法中,向适配器列表中注册一个新的 AdvisorAdapter 实例。
+
+```java
+/**
+ * 注册一个Advisor适配器。
+ * @param adapter 要注册的Advisor适配器
+ */
+@Override
+public void registerAdvisorAdapter(AdvisorAdapter adapter) {
+ this.adapters.add(adapter);
+}
+```
+
+在`org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#adapters`字段中,用于存储 AdvisorAdapter 实例
+
+```java
+private final List adapters = new ArrayList<>(3);
+```
+
+**适配器转换拦截器**
+
+在`org.springframework.aop.framework.JdkDynamicAopProxy#invoke`方法中,JDK动态代理入口中,获取指定方法的拦截链。
+
+```java
+@Override
+@Nullable
+public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // ... [代码部分省略以简化]
+
+ try {
+ // ... [代码部分省略以简化]
+
+ // Get the interception chain for this method.
+ List