diff --git a/spring-aop/pom.xml b/spring-aop/pom.xml
index 02a6c1b..0a2ba83 100644
--- a/spring-aop/pom.xml
+++ b/spring-aop/pom.xml
@@ -39,6 +39,7 @@
spring-aop-metadataAwareAspectInstanceFactory
spring-aop-aspectJAdvisorFactory
spring-aop-beanFactoryAspectJAdvisorsBuilder
+ spring-aop-beanFactoryAdvisorRetrievalHelper
4.0.0
diff --git a/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md
new file mode 100644
index 0000000..a887d9c
--- /dev/null
+++ b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md
@@ -0,0 +1,162 @@
+## BeanFactoryAdvisorRetrievalHelper
+
+- [BeanFactoryAdvisorRetrievalHelper](#beanfactoryadvisorretrievalhelper)
+ - [一、基本信息](#一基本信息)
+ - [二、基本描述](#二基本描述)
+ - [三、主要功能](#三主要功能)
+ - [四、最佳实践](#四最佳实践)
+ - [五、源码分析](#五源码分析)
+ - [六、常见问题](#六常见问题)
+
+### 一、基本信息
+
+✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
+
+### 二、基本描述
+
+`BeanFactoryAdvisorRetrievalHelper` 类是 Spring AOP 框架中的辅助工具,用于在 Bean 工厂中检索 Advisor,这些 Advisor 定义了切面逻辑,可以在目标 Bean 的方法调用中织入相应的通知。
+
+### 三、主要功能
+
+1. **协助Advisor的检索**
+ + 帮助 Spring AOP 框架在应用程序的 Bean 工厂中查找与目标 Bean 相关的 Advisor。
+
+2. **解析Advisor的Bean名称**
+ + 解析 Advisor 在 Spring 容器中的 Bean 名称,并根据名称从 Bean 工厂中获取相应的 Advisor 实例。
+
+3. **适配不同类型的Advisor**
+ + 支持不同类型的 Advisor,包括前置通知(BeforeAdvice)、后置通知(AfterAdvice)、环绕通知(AroundAdvice)等,能够正确地应用到目标 Bean 上。
+
+4. **辅助创建代理**
+
+ + 辅助 Spring 容器创建代理对象,并将 Advisor 中定义的通知逻辑织入到目标 Bean 的方法调用中。
+
+### 四、最佳实践
+
+使用 `BeanFactoryAdvisorRetrievalHelper` 类来从一个默认的 Bean 工厂中检索 Advisor,并打印出这些 Advisor 的列表。首先,我们创建一个默认的 Bean 工厂,并向其注册一个名为 "myAdvisor" 的 Advisor。然后,我们创建了 `BeanFactoryAdvisorRetrievalHelper` 实例,并将 Bean 工厂传入其中。接着,通过调用 `findAdvisorBeans()` 方法,我们获取了 Bean 工厂中的 Advisor 列表,并通过循环遍历的方式打印出每个 Advisor 的信息。
+
+```java
+public class BeanFactoryAdvisorRetrievalHelperDemo {
+
+ public static void main(String[] args) {
+ // 创建一个默认的 Bean 工厂
+ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+ // 向 Bean 工厂注册一个名为 "myAdvisor" 的 Advisor
+ beanFactory.registerSingleton("myAdvisor", new MyAdvisor());
+
+ // 创建 BeanFactoryAdvisorRetrievalHelper 实例,并传入 Bean 工厂
+ BeanFactoryAdvisorRetrievalHelper helper = new BeanFactoryAdvisorRetrievalHelper(beanFactory);
+ // 获取 Bean 工厂中的 Advisor 列表
+ List advisors = helper.findAdvisorBeans();
+ // 打印 Advisors
+ advisors.forEach(System.out::println);
+ }
+}
+```
+
+`MyAdvisor` 类是一个自定义的 Advisor,继承自 `AbstractPointcutAdvisor`,用于定义切面的逻辑。在该类中,`getPointcut()` 方法返回一个始终为真的 Pointcut,表示适用于所有的连接点;`getAdvice()` 方法返回一个空的 Advice,表示不对目标方法添加任何额外的通知逻辑。因此,该 Advisor 没有实际的业务逻辑,仅作为演示目的。
+
+```java
+public class MyAdvisor extends AbstractPointcutAdvisor {
+
+ @Override
+ public Pointcut getPointcut() {
+ return Pointcut.TRUE;
+ }
+
+ @Override
+ public Advice getAdvice() {
+ return Advisor.EMPTY_ADVICE;
+ }
+}
+```
+
+运行结果,成功地从 Bean 工厂中获取了Advisor。
+
+```java
+com.xcs.spring.MyAdvisor@1f7030a6
+```
+
+### 五、源码分析
+
+在`org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans`方法中,主要功能是在当前的 Bean 工厂中查找所有符合条件的 Advisor Beans。它忽略了 FactoryBeans,并排除了当前正在创建中的 Beans。该方法首先确定 Advisor Bean 的名称列表,如果尚未缓存,则通过 `BeanFactoryUtils.beanNamesForTypeIncludingAncestors()` 方法获取。然后,它遍历这些 Advisor Bean 的名称,检查它们是否符合条件,并将符合条件的 Advisor Bean 添加到结果列表中。在添加之前,它会检查该 Bean 是否当前正在创建中,如果是,则跳过。最后,返回包含所有符合条件的 Advisor Beans 的列表。
+
+```java
+/**
+ * 在当前 Bean 工厂中查找所有符合条件的 Advisor Bean,
+ * 忽略 FactoryBeans,并排除当前正在创建的 Bean。
+ * @return {@link org.springframework.aop.Advisor} Bean 的列表
+ * @see #isEligibleBean
+ */
+public List findAdvisorBeans() {
+ // 如果未缓存 Advisor Bean 的名称列表,则确定该列表。
+ String[] advisorNames = this.cachedAdvisorBeanNames;
+ if (advisorNames == null) {
+ // 不要在这里初始化 FactoryBeans我们需要保持所有常规 Bean 未初始化,以便自动代理创建器应用到它们上!
+ advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
+ this.beanFactory, Advisor.class, true, false);
+ this.cachedAdvisorBeanNames = advisorNames;
+ }
+ if (advisorNames.length == 0) {
+ return new ArrayList<>();
+ }
+
+ List advisors = new ArrayList<>();
+ // 遍历 Advisor Bean 名称列表
+ for (String name : advisorNames) {
+ // 检查 Bean 是否符合条件
+ if (isEligibleBean(name)) {
+ // 如果 Bean 当前正在创建中,则跳过
+ if (this.beanFactory.isCurrentlyInCreation(name)) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Skipping currently created advisor '" + name + "'");
+ }
+ }
+ else {
+ try {
+ // 尝试获取 Advisor Bean,并添加到列表中
+ advisors.add(this.beanFactory.getBean(name, Advisor.class));
+ }
+ catch (BeanCreationException ex) {
+ Throwable rootCause = ex.getMostSpecificCause();
+ if (rootCause instanceof BeanCurrentlyInCreationException) {
+ BeanCreationException bce = (BeanCreationException) rootCause;
+ String bceBeanName = bce.getBeanName();
+ // 如果当前 Bean 依赖于正在创建的 Bean,则跳过
+ if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Skipping advisor '" + name +
+ "' with dependency on currently created bean: " + ex.getMessage());
+ }
+ // 忽略表示对当前正在尝试进行通知的 Bean 的引用。
+ // 我们希望找到除当前正在创建的 Bean 本身之外的其他 Advisor。
+ continue;
+ }
+ }
+ // 如果获取 Advisor Bean 失败,则抛出异常
+ throw ex;
+ }
+ }
+ }
+ }
+ return advisors;
+}
+```
+
+### 六、常见问题
+
+1. **忽略FactoryBeans**
+
+ + 在 `findAdvisorBeans()` 方法中,该类会忽略 FactoryBeans,只处理常规的 Advisor Beans。这是因为 FactoryBeans 可能会在初始化时产生副作用,而 `BeanFactoryAdvisorRetrievalHelper` 需要保持所有常规 Beans 未初始化,以便自动代理创建器能够正确地应用于它们。
+
+2. **排除当前正在创建的Beans**
+
+ + 在遍历 Advisor Beans 名称列表时,`findAdvisorBeans()` 方法会排除当前正在创建中的 Beans。这是为了避免在 Bean 的创建过程中引入不稳定的代理逻辑。
+
+3. **错误处理**
+
+ + 当尝试获取 Advisor Bean 时,可能会抛出 `BeanCreationException` 异常。`BeanFactoryAdvisorRetrievalHelper` 需要正确处理这些异常情况,例如,当 Advisor Bean 的依赖 Bean 正在创建中时,可以选择跳过该 Advisor。
+
+4. **缓存机制**
+
+ + 为了提高性能,`BeanFactoryAdvisorRetrievalHelper` 类使用了缓存机制来存储 Advisor Bean 的名称列表。需要注意,在 Bean 工厂中添加或删除 Advisor Bean 时,需要更新缓存以确保数据的一致性。
\ No newline at end of file
diff --git a/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/pom.xml b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/pom.xml
new file mode 100644
index 0000000..ffc3337
--- /dev/null
+++ b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ com.xcs.spring
+ spring-aop
+ 0.0.1-SNAPSHOT
+
+
+ 4.0.0
+ spring-aop-beanFactoryAdvisorRetrievalHelper
+
+
\ No newline at end of file
diff --git a/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/BeanFactoryAdvisorRetrievalHelperDemo.java b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/BeanFactoryAdvisorRetrievalHelperDemo.java
new file mode 100644
index 0000000..95ee8f5
--- /dev/null
+++ b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/BeanFactoryAdvisorRetrievalHelperDemo.java
@@ -0,0 +1,24 @@
+package com.xcs.spring;
+
+import org.springframework.aop.Advisor;
+import org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+
+import java.util.List;
+
+public class BeanFactoryAdvisorRetrievalHelperDemo {
+
+ public static void main(String[] args) {
+ // 创建一个默认的 Bean 工厂
+ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+ // 向 Bean 工厂注册一个名为 "myAspect" 的 Advisor
+ beanFactory.registerSingleton("myAspect", new MyAdvisor());
+
+ // 创建 BeanFactoryAdvisorRetrievalHelper 实例,并传入 Bean 工厂
+ BeanFactoryAdvisorRetrievalHelper helper = new BeanFactoryAdvisorRetrievalHelper(beanFactory);
+ // 获取 Bean 工厂中的 Advisor 列表
+ List advisors = helper.findAdvisorBeans();
+ // 打印 Advisors
+ advisors.forEach(System.out::println);
+ }
+}
diff --git a/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvisor.java b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvisor.java
new file mode 100644
index 0000000..df3aca9
--- /dev/null
+++ b/spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvisor.java
@@ -0,0 +1,19 @@
+package com.xcs.spring;
+
+import org.aopalliance.aop.Advice;
+import org.springframework.aop.Advisor;
+import org.springframework.aop.Pointcut;
+import org.springframework.aop.support.AbstractPointcutAdvisor;
+
+public class MyAdvisor extends AbstractPointcutAdvisor {
+
+ @Override
+ public Pointcut getPointcut() {
+ return Pointcut.TRUE;
+ }
+
+ @Override
+ public Advice getAdvice() {
+ return Advisor.EMPTY_ADVICE;
+ }
+}
diff --git a/spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md b/spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md
index 47cd561..5dee7ab 100644
--- a/spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md
+++ b/spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md
@@ -85,6 +85,13 @@ public class MyService {
}
```
+运行结果,显示了两个 Advisor 对象的信息,它们分别对应着切面类 `MyAspect` 中的 `before()` 和 `after()` 方法,并针对相同的切点表达式 `execution(* com.xcs.spring.MyService.doSomething(..))`。
+
+```java
+InstantiationModelAwarePointcutAdvisor: expression [execution(* com.xcs.spring.MyService.doSomething(..))]; advice method [public void com.xcs.spring.MyAspect.before()]; perClauseKind=SINGLETON
+InstantiationModelAwarePointcutAdvisor: expression [execution(* com.xcs.spring.MyService.doSomething(..))]; advice method [public void com.xcs.spring.MyAspect.after()]; perClauseKind=SINGLETON
+```
+
### 五、源码分析
在`org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors`方法中,主要负责在当前的 Bean 工厂中查找使用 AspectJ 注解标记的切面 Bean,并将其转换为 Spring AOP Advisors 的列表。它遍历所有的 Bean 名称,识别切面 Bean,并根据其实例化模型(单例或多例)创建对应的 AspectJ Advisors。在处理过程中,还会缓存单例切面的 Advisors,以提高性能。