AdvisorChainFactory源码分析

AdvisorAdapterRegistry源码分析
master
linlei 2024-04-19 11:11:18 +08:00
parent 62cb6744d7
commit 0f740c2cd6
12 changed files with 584 additions and 0 deletions

View File

@ -220,6 +220,8 @@
- [BeanFactoryAspectJAdvisorsBuilder](spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md):构建@AspectJ注解切面生成Spring AOP Advisors。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md):帮助检索并管理 Spring AOP 中的 Advisor Beans。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AnnotationAwareAspectJAutoProxyCreator](spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/README.md)创建AOP代理以应用AspectJ风格的切面。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
- [AdvisorChainFactory](spring-aop/spring-aop-advisorChainFactory/README.md)创建Advisor链的工厂接口。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
- [AdvisorAdapterRegistry](spring-aop/spring-aop-advisorAdapterRegistry/README.md)适配各种Advice到AOP拦截器注册和管理Advisor适配器。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
+ Spring AOT

View File

@ -33,6 +33,8 @@
<module>spring-aop-beanFactoryAspectJAdvisorsBuilder</module>
<module>spring-aop-beanFactoryAdvisorRetrievalHelper</module>
<module>spring-aop-proxyFactory</module>
<module>spring-aop-advisorChainFactory</module>
<module>spring-aop-advisorAdapterRegistry</module>
</modules>
<modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,240 @@
## AdvisorAdapterRegistry
- [AdvisorAdapterRegistry](#AdvisorAdapterRegistry)
- [一、基本信息](#一基本信息)
- [二、基本描述](#二基本描述)
- [三、主要功能](#三主要功能)
- [四、接口源码](#四接口源码)
- [五、主要实现](#五主要实现)
- [六、最佳实践](#六最佳实践)
- [七、源码分析](#七源码分析)
- [八、常见问题](#八常见问题)
### 一、基本信息
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
### 二、基本描述
`AdvisorAdapterRegistry`接口是Spring AOP中的关键接口之一用于注册和管理AdvisorAdapters它负责将Advisor与AOP框架所支持的特定拦截器关联起来实现对目标对象方法的拦截和增强从而实现面向切面编程的功能。
### 三、主要功能
1. **注册AdvisorAdapters**
+ 允许我们注册自定义的AdvisorAdapters以适配新的拦截器类型或扩展现有的拦截器逻辑。
3. **支持内置拦截器**
+ 默认实现预先注册了一些标准的AdvisorAdapters用于支持Spring AOP框架内置的拦截器类型如BeforeAdvice、AfterReturningAdvice等
### 四、接口源码
作为Advisor适配器的注册表。它提供了方法来包装给定的advice为Advisor并获取Advisor中的拦截器数组。通过注册AdvisorAdapter实现了Advisor与AOP框架所支持的不同拦截器类型之间的适配。
```java
/**
* Advisor适配器注册表的接口。
*
* <p><i>这是一个SPI接口不应该由任何Spring用户实现。</i>
*
* @author Rod Johnson
* @author Rob Harrop
*/
public interface AdvisorAdapterRegistry {
/**
* 返回一个包装了给定advice的{@link Advisor}。
* <p>默认情况下应该至少支持
* {@link org.aopalliance.intercept.MethodInterceptor},
* {@link org.springframework.aop.MethodBeforeAdvice},
* {@link org.springframework.aop.AfterReturningAdvice},
* {@link org.springframework.aop.ThrowsAdvice}。
* @param advice 应该是一个advice的对象
* @return 包装了给定advice的Advisor永远不会为{@code null}
* 如果advice参数本身就是一个Advisor则直接返回
* @throws UnknownAdviceTypeException 如果没有注册的advisor adapter
* 能够包装给定的advice
*/
Advisor wrap(Object advice) throws UnknownAdviceTypeException;
/**
* 返回一组AOP Alliance MethodInterceptors以允许在基于拦截的框架中使用给定的Advisor。
* <p>如果Advisor是一个{@link org.springframework.aop.PointcutAdvisor}
* 则不必担心与其关联的切入点表达式只需返回一个拦截器。
* @param advisor 要查找拦截器的Advisor
* @return 一组MethodInterceptor用于暴露此Advisor的行为
* @throws UnknownAdviceTypeException 如果Advisor类型
* 不被任何注册的AdvisorAdapter理解
*/
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
/**
* 注册给定的{@link AdvisorAdapter}。
* 注意不需要为AOP Alliance Interceptors或Spring Advices注册适配器
* 这些必须由{@code AdvisorAdapterRegistry}的实现自动识别。
* @param adapter 理解特定Advisor或Advice类型的AdvisorAdapter
*/
void registerAdvisorAdapter(AdvisorAdapter adapter);
}
```
### 五、主要实现
1. **DefaultAdvisorAdapterRegistry**
+ 默认Advisor适配器注册表实现预先注册了标准的Advisor适配器支持将各种类型的Advice适配到AOP Alliance MethodInterceptor并允许我们注册自定义的Advisor适配器从而实现了Advisor与拦截器之间的灵活适配和管理。
### 六、最佳实践
使用`DefaultAdvisorAdapterRegistry`来包装自定义的`MyMethodBeforeAdvice`,并获取其对应的拦截器数组。通过`wrap()`方法将`MyMethodBeforeAdvice`转换为`Advisor`,然后使用`getInterceptors()`方法获取该`Advisor`中的拦截器数组,最后输出拦截器的信息。
```java
public class AdvisorAdapterRegistryDemo {
public static void main(String[] args) {
// 创建默认的Advisor适配器注册表实例
DefaultAdvisorAdapterRegistry registry = new DefaultAdvisorAdapterRegistry();
// 包装给定的MyMethodBeforeAdvice为Advisor
Advisor advisor = registry.wrap(new MyMethodBeforeAdvice());
// 获取Advisor中的拦截器数组
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// 输出拦截器信息
for (MethodInterceptor interceptor : interceptors) {
System.out.println("interceptor = " + interceptor);
}
}
}
```
### 七、源码分析
实现了`AdvisorAdapterRegistry`接口的默认实现`DefaultAdvisorAdapterRegistry`支持将不同类型的Advice对象适配为Advisor并提供获取Advisor中拦截器数组的功能。它预先注册了一些常见的Advisor适配器并允许用户注册自定义的适配器。其核心逻辑包括将Advice对象包装为Advisor、根据Advisor获取拦截器数组以及注册Advisor适配器。
```java
/**
* AdvisorAdapterRegistry接口的默认实现。
* 支持{@link org.aopalliance.intercept.MethodInterceptor}、
* {@link org.springframework.aop.MethodBeforeAdvice}、
* {@link org.springframework.aop.AfterReturningAdvice}、
* {@link org.springframework.aop.ThrowsAdvice}。
*
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
*/
@SuppressWarnings("serial")
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
// 用于存储注册的AdvisorAdapter的列表
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
/**
* 创建一个新的DefaultAdvisorAdapterRegistry实例并注册已知的适配器。
* 这里的“已知的适配器”包括MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter。
*/
public DefaultAdvisorAdapterRegistry() {
// 注册MethodBeforeAdviceAdapter适配器
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
// 注册AfterReturningAdviceAdapter适配器
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
// 注册ThrowsAdviceAdapter适配器
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
/**
* 将给定的adviceObject包装为Advisor。
* 如果adviceObject已经是Advisor则直接返回
* 如果不是Advice类型则抛出UnknownAdviceTypeException
* 如果advice是MethodInterceptor类型则创建一个DefaultPointcutAdvisor并返回
* 否则遍历已注册的AdvisorAdapter找到支持advice的适配器创建一个DefaultPointcutAdvisor并返回。
*
* @param adviceObject 要包装为Advisor的Advice对象
* @return 包装后的Advisor对象
* @throws UnknownAdviceTypeException 如果adviceObject无法被识别为Advisor或Advice
*/
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// 对于MethodInterceptor类型的Advice不需要适配器直接创建Advisor并返回
return new DefaultPointcutAdvisor(advice);
}
// 遍历已注册的AdvisorAdapter查找支持当前Advice的适配器
for (AdvisorAdapter adapter : this.adapters) {
// 检查是否支持当前Advice
if (adapter.supportsAdvice(advice)) {
// 创建Advisor并返回
return new DefaultPointcutAdvisor(advice);
}
}
// 如果无法找到合适的适配器,抛出异常
throw new UnknownAdviceTypeException(advice);
}
/**
* 获取Advisor中的拦截器数组。
* 如果Advisor中的Advice是MethodInterceptor类型则直接返回
* 否则遍历已注册的AdvisorAdapter找到支持Advisor中的Advice的适配器并获取对应的拦截器返回拦截器数组。
*
* @param advisor 要获取拦截器数组的Advisor对象
* @return 包含Advisor中拦截器的数组
* @throws UnknownAdviceTypeException 如果Advisor中的Advice无法被识别
*/
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
// 如果Advisor中的Advice是MethodInterceptor类型直接将其添加到拦截器数组中
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 遍历已注册的AdvisorAdapter查找支持Advisor中的Advice的适配器
for (AdvisorAdapter adapter : this.adapters) {
// 如果适配器支持当前Advice获取其拦截器并添加到数组中
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
// 如果拦截器数组为空,表示未找到适配器,抛出异常
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advice);
}
// 将拦截器数组转换为数组并返回
return interceptors.toArray(new MethodInterceptor[0]);
}
/**
* 注册给定的AdvisorAdapter。
*
* @param adapter 要注册的AdvisorAdapter对象
*/
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
```
### 八、常见问题
1. **适配器未注册**
- 如果尝试使用某种类型的Advice对象而对应的适配器未被注册到`AdvisorAdapterRegistry`实例中可能会导致无法将Advice对象包装为Advisor进而导致运行时异常。
2. **适配器不支持特定类型的Advice**
- 每个Advisor适配器可能只支持特定类型的Advice如果尝试使用一个不受支持的Advice对象可能会导致运行时异常或者Advice对象无法被正确地适配为Advisor。
3. **Advice对象无法被正确适配**
- 某些特定类型的Advice对象可能无法被任何已注册的适配器正确地适配为Advisor。这可能是因为没有适合该Advice类型的适配器或者适配器的实现存在缺陷。

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xcs.spring</groupId>
<artifactId>spring-aop</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-aop-advisorAdapterRegistry</artifactId>
</project>

View File

@ -0,0 +1,22 @@
package com.xcs.spring;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry;
public class AdvisorAdapterRegistryDemo {
public static void main(String[] args) {
// 创建默认的Advisor适配器注册表实例
DefaultAdvisorAdapterRegistry registry = new DefaultAdvisorAdapterRegistry();
// 包装给定的MyMethodBeforeAdvice为Advisor
Advisor advisor = registry.wrap(new MyMethodBeforeAdvice());
// 获取Advisor中的拦截器数组
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// 输出拦截器信息
for (MethodInterceptor interceptor : interceptors) {
System.out.println("interceptor = " + interceptor);
}
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,216 @@
## AdvisorChainFactory
- [AdvisorChainFactory](#AdvisorChainFactory)
- [一、基本信息](#一基本信息)
- [二、基本描述](#二基本描述)
- [三、主要功能](#三主要功能)
- [四、接口源码](#四接口源码)
- [五、主要实现](#五主要实现)
- [六、最佳实践](#六最佳实践)
- [七、源码分析](#七源码分析)
- [八、常见问题](#八常见问题)
### 一、基本信息
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
### 二、基本描述
`AdvisorChainFactory`接口是Spring AOP中负责创建顾问链的工厂接口通过`getInterceptorsAndDynamicInterceptionAdvice()`方法,它能够将一组顾问对象转换为拦截器数组,用于管理和执行切面逻辑,提供了灵活性和可扩展性来定制切面的执行方式。
### 三、主要功能
1. **创建顾问链Advisor Chain**
+ 通过`getInterceptorsAndDynamicInterceptionAdvice()`方法,将一组顾问对象转换为拦截器数组,形成顾问链,用于在目标方法执行前后执行特定的操作。
2. **动态顾问链的创建**
+ 可以根据运行时的情况动态地创建顾问链,例如根据目标对象的类型或方法签名动态地决定哪些通知要被执行。
### 四、接口源码
`AdvisorChainFactory`接口 用于创建Advisor链的工厂接口。其中的方法 `getInterceptorsAndDynamicInterceptionAdvice()` 接受AOP配置`Advised`对象、被代理的方法以及目标类并返回一个包含MethodInterceptors的列表用于配置Advisor链。这个接口的目的是根据给定的配置确定在代理方法执行时应该应用哪些拦截器以及是否需要动态匹配方法。
```java
/**
* Advisor链工厂的工厂接口。
* Factory interface for advisor chains.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public interface AdvisorChainFactory {
/**
* 根据给定的Advisor链配置确定一组MethodInterceptor对象。
* Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
* for the given advisor chain configuration.
* @param config 表示AOP配置的Advised对象
* @param method 被代理的方法
* @param targetClass 目标类可能为null表示没有目标对象的代理在这种情况下方法的声明类是下一个最佳选择
* @return 一个MethodInterceptors的列表也可能包括InterceptorAndDynamicMethodMatchers
*/
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
}
```
### 五、主要实现
1. **DefaultAdvisorChainFactory**
+ 负责根据给定的AOP配置、被代理的方法和目标类确定应该应用哪些拦截器并支持动态方法匹配和缓存机制以提供高效的顾问链创建功能
### 六、最佳实践
使用`DefaultAdvisorChainFactory`类来创建Advisor链。首先创建了一个`AdvisedSupport`对象,配置了前置通知和后置返回通知。然后,指定了目标类和目标方法。接着,实例化了`DefaultAdvisorChainFactory`类,并调用其`getInterceptorsAndDynamicInterceptionAdvice()`方法获取Advisor链。最后打印了Advisor链中的拦截器。
```java
public class AdvisorChainFactoryDemo {
public static void main(String[] args) throws NoSuchMethodException {
// 创建AOP配置对象
AdvisedSupport config = new AdvisedSupport();
// 添加前置通知
config.addAdvice(new MyMethodBeforeAdvice());
// 添加后置返回通知
config.addAdvice(new MyAfterReturningAdvice());
// 设置目标类
Class<MyService> targetClass = MyService.class;
// 获取目标方法
Method method = targetClass.getDeclaredMethod("doSomething");
// 创建默认的Advisor链工厂实例
DefaultAdvisorChainFactory chainFactory = new DefaultAdvisorChainFactory();
// 获取Advisor链
List<Object> chain = chainFactory.getInterceptorsAndDynamicInterceptionAdvice(config, method, targetClass);
// 打印Advisor链中的拦截器
chain.forEach(System.out::println);
}
}
```
运行结果显示了Advisor链中的两个拦截器分别是`MethodBeforeAdviceInterceptor`和`AfterReturningAdviceInterceptor`。这些拦截器是根据配置的前置通知和后置返回通知生成的,用于在目标方法执行前后进行相应的操作。
```java
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@215be6bb
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor@4439f31e
```
### 七、源码分析
`DefaultAdvisorChainFactory`类。它提供了一种简单但确定的方法,根据给定的`Advised`对象在方法级别确定通知链的构建顺序。通过遍历配置的Advisor数组并根据Advisor的类型和Pointcut来确定应该应用哪些拦截器最终返回一个拦截器列表。在此过程中它支持动态方法匹配和引入拦截器的处理并提供了一个缓存机制来提高性能。
```java
/**
* 给定一个 {@link Advised} 对象,为一个方法确定一个通知链的简单但确定的方法。总是重新构建每个通知链;
* 子类可以提供缓存功能。
*
* @author Juergen Hoeller
* @author Rod Johnson
* @author Adrian Colyer
* @since 2.0.3
*/
@SuppressWarnings("serial")
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// 获取Advisor适配器注册表
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 获取AOP配置中的所有Advisor
Advisor[] advisors = config.getAdvisors();
// 创建一个拦截器列表
List<Object> interceptorList = new ArrayList<>(advisors.length);
// 获取实际类
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历所有Advisor
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// 添加条件性地。
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 获取Advisor的Pointcut和MethodMatcher
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
// 检查是否存在匹配的IntroductionAdvisor
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
// 如果匹配则将Interceptor添加到拦截器列表中
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// 如果是动态匹配则创建一个新的InterceptorAndDynamicMethodMatcher对象
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
// 否则直接添加Interceptor
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
// 如果是IntroductionAdvisor则直接获取Interceptor并添加到拦截器列表中
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
// 对于其他类型的Advisor直接获取Interceptor并添加到拦截器列表中
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 返回拦截器列表
return interceptorList;
}
/**
* 判断Advisor中是否存在匹配的引入拦截器。
*/
private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) {
for (Advisor advisor : advisors) {
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(actualClass)) {
return true;
}
}
}
return false;
}
}
```
### 八、常见问题
1. **拦截器未被正确应用**
+ 如果`AdvisorChainFactory`未正确构建Advisor链可能会导致拦截器未按预期应用于目标方法。
2. **动态方法匹配错误**
+ 如果动态方法匹配器DynamicMethodMatcher未正确配置或应用可能会导致拦截器未在预期条件下执行。
3. **引入拦截器未生效**
+ 如果引入拦截器IntroductionInterceptor未被正确添加到Advisor链中可能会导致引入功能无法正常工作。

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xcs.spring</groupId>
<artifactId>spring-aop</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-aop-advisorChainFactory</artifactId>
</project>

View File

@ -0,0 +1,30 @@
package com.xcs.spring;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import java.lang.reflect.Method;
import java.util.List;
public class AdvisorChainFactoryDemo {
public static void main(String[] args) throws NoSuchMethodException {
// 创建AOP配置对象
AdvisedSupport config = new AdvisedSupport();
// 添加前置通知
config.addAdvice(new MyMethodBeforeAdvice());
// 添加后置返回通知
config.addAdvice(new MyAfterReturningAdvice());
// 设置目标类
Class<MyService> targetClass = MyService.class;
// 获取目标方法
Method method = targetClass.getDeclaredMethod("doSomething");
// 创建默认的Advisor链工厂实例
DefaultAdvisorChainFactory chainFactory = new DefaultAdvisorChainFactory();
// 获取Advisor链
List<Object> chain = chainFactory.getInterceptorsAndDynamicInterceptionAdvice(config, method, targetClass);
// 打印Advisor链中的拦截器
chain.forEach(System.out::println);
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,8 @@
package com.xcs.spring;
public class MyService {
public void doSomething(){
System.out.println("doSomething");
}
}