【Spring源码三千问】Advice、Advisor、Advised都是什么接口?

article/2025/10/29 18:20:40

Advice、Advisor、Advised都是什么接口?

  • 前言
  • 版本约定
  • 正文
    • Advice、Advisor、Advised 类图
    • Advice
      • MethodInterceptor
    • Advisor
      • PointcutAdvisor
    • Advised
      • Spring AOP 代理类可以转换为 Advised 类型
  • 小结

前言

在看 Spring AOP 的源码时,经常可以看到 Advice、Advisor、Advised 等接口,它们长的很像,初次见面时,看着都有些让人犯糊涂,但是却拥有着不同的功能。
理解这些接口的作用,能够让我们更好的理解 Spring AOP。

版本约定

Spring 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)

正文

  • Advice: org.aopalliance.aop.Advice
    “通知”,表示 Aspect 在特定的 Join point 采取的操作。包括 “around”, “before” and “after 等

  • Pointcut: org.springframework.aop.Pointcut
    “切点”,它是用来匹配连接点 Join point 的,可以说"Pointcut"表示的是"Join point"的集合。

  • Advisor: org.springframework.aop.Advisor
    “通知者”,它持有 Advice,是 Spring AOP 的一个基础接口。

  • Advised: org.springframework.aop.framework.Advised
    AOP 代理工厂配置类接口。提供了操作和管理 Advice 和 Advisor 的能力。

下面我们通过类的继续关系图的方式,来从一个比较高的视角来观察一下 Advice、Advisor、Advised 接口。

通过类图,能让我们有一个全面的了解,而不是钻进某一个类里面,只见树木,不见森林!

Advice、Advisor、Advised 类图

AdviceAdvisorUML

  1. Advisor 可以获取到 Advice。
  2. PointcutAdvisor 可以获取到 Pointcut 和 Advice。
    Pointcut 可以匹配 join point,Advice 是具体的通知,所以,PointcutAdvisor 是一个功能完善接口。
  3. Advised 是 AOP 代理工厂配置类接口,它可以操作和管理 Advice 和 Advisor,它的实现类有 ProxyFactoryAspectJProxyFactory,用于生成AOP 代理类。

AdviceAdvisorAdvised

Advice

Advice

Advice 大体上分为了三类:BeforeAdvice、MethodInterceptor、AfterAdvice

可以看出,MethodInterceptor 是功能最强大的,它能够处理 BeforeAdvice、AroundAdvice、AfterAdvice、ThrowsAdvice、@Valid方法参数校验、@Async异步等

MethodInterceptor

MethodInterceptor

MethodInterceptor 是功能最强大的,它能够处理 BeforAdvice、AroundAdvice、AfterAdvice、ThrowsAdvice、限流、@Valid方法参数校验、@Async异步、事务等
MethodInterceptor 除了可以处理 Advice 类的通知拦截外,还是一个比较能用的方法拦截接口。

例如:给接口 FooService 添加一个方法拦截器

FooService fooService = ProxyFactory.getProxy(FooService.class, new MyInterceptor());

在执行 FooService 的任意方法时,都会经过 MyInterceptor 的处理。

ProxyFactory#getProxy(Class, Interceptor)
它可以为给定接口和 Interceptor 拦截器创建代理类。
这个方法是一个静态方法,可以给单个 Interceptor 拦截器创建代理,这个拦截器自己处理所有的调用,而不是委托给目标(如远程调用代理)。

public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
}

Advisor

Advisor

Advisor 大体分为了三类:PointcutAdvisor、IntroductionAdvisor、PrototypePlaceholderAdvisor
其中,用到的最多的就是 PointcutAdvisor,它涵盖了绝大部分的 Advisor。

PointcutAdvisor

PointcutAdvisor 是一个功能完善接口,也是 Spring AOP 中使用最多的,它涵盖了绝大部分的 Advisor。

通过 PointcutAdvisor 可以获取到 Pointcut 和 Advice。Pointcut 可以完成 join point 的匹配,而 Advice 就是在 join point 上具体要执行的"通知"。

Advised

Advised
proxyFactory

Advised 是 AOP 代理工厂配置类接口。

它的实现类有:ProxyFactory、AspectJProxyFactory、ProxyFactoryBean。
Advised 提供了操作和管理 Advice 和 Advisor 的能力,所以,ProxyFactory 实现 Advised 之后,就可以方便的获取和操作 Advice、Advisor,从而创建 AOP 代理类了。

Advised、ProxyConfig、AdvisedSupport 都是跟 Spring AOP 代理配置相关的接口和类,它们可以统一 Spring AOP 的代理配置。

Spring AOP 代理类可以转换为 Advised 类型

Spring AOP 在产生代理类时,会调用 AopProxyUtils#completeProxiedInterfaces(),将 AdvisedSpringProxy 添加为代理类实现的接口。
这样,所有的 Spring AOP 代理类都实现了 Advised 接口,所以,Spring AOP 代理类可以转换为 Advised 类型

既然 Spring AOP 代理类可以转换为 Advised 类型,那么代理类就可以操作 Advice 和 Advisor 了。
我们可以测试一下:

@RestController
@SpringBootApplication
//@EnableAspectJAutoProxy
public class AopApplication {@Resourceprivate FoService foService;@Resourceprivate FoService foService2;@Resourceprivate XoService xoService;public static void main(String[] args) {SpringApplication app = new SpringApplication(AopApplication.class);app.setBannerMode(Banner.Mode.OFF);app.run(args);}@GetMapping("/status")public String status() {if (foService instanceof Advised) {// 动态添加 Advice ((Advised) foService).addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("动态添加:before execute:" + method);}});}foService.doBiz();System.out.println(">>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<");// 测试对相同 bean 和不同 bean 的影响foService2.doBiz();xoService.doBiz();return ObjectUtils.identityToString(foService);}
}

输出:

before...public java.lang.String com.kvn.aop.advised.FoService.doBiz()
动态添加:before execute:public java.lang.String com.kvn.aop.advised.FoService.doBiz()
FoooooooService#doBiz
finally...public java.lang.String com.kvn.aop.advised.FoService.doBiz()
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<
before...public java.lang.String com.kvn.aop.advised.FoService.doBiz()
动态添加:before execute:public java.lang.String com.kvn.aop.advised.FoService.doBiz()
FoooooooService#doBiz
finally...public java.lang.String com.kvn.aop.advised.FoService.doBiz()
before...public java.lang.String com.kvn.aop.advised.XoService.doBiz()
XxxxxoService#doBiz
finally...public java.lang.String com.kvn.aop.advised.XoService.doBiz()

可以看出:
Spring AOP 代理类都可以转换为 Advised 接口,并可以使用它来操作 Advice 和 Advisor。
如果更改了 FooService 的 Advice 后,对所有注入 FooService 的地方都有影响,但是不会影响到其他类型的 bean。

原因分析:
Spring AOP 代理类的 Advice、Advisor 等 ProxyConfig 配置是保存在 ProxyFactory 中的。
由于 Spring AOP 代理对象每次都是通过 new ProxyFactory 来创建的,对于不同的 proxy bean 而言,ProxyConfig 代理配置都是各自持有,所以,对 bean 对应的 Advised 的操作只会体现在这一个类型的 bean 上面。
不同类型的 bean 之间是互不影响的。测试例子中也证明了这一点

关于 Spring AOP 产生代理的过程可以点击传送门: 如何为 Pointcut 匹配的类生成动态代理类

小结

Advice、Advisor、Advised 都是 Spring AOP 相关的基本接口,理解这些接口的作用,对于更好的理解 Spring AOP 有很大的好处:

  • Advice: org.aopalliance.aop.Advice
    “通知”,表示 Aspect 在特定的 Join point 采取的操作。包括 “around”, “before” and “after 等
    Advice 大体上分为了三类:BeforeAdvice、MethodInterceptor、AfterAdvice
    MethodInterceptor 是功能最强大的,是一个通用的方法拦截接口,它能够处理 BeforeAdvice、AroundAdvice、AfterAdvice、ThrowsAdvice、@Valid方法参数校验、@Async异步等

  • Advisor: org.springframework.aop.Advisor
    “通知者”,它持有 Advice,是 Spring AOP 的一个基础接口。
    它的子接口 PointcutAdvisor 是一个功能完善接口,它涵盖了绝大部分的 Advisor。

  • Advised: org.springframework.aop.framework.Advised
    AOP 代理工厂配置类接口。提供了操作和管理 Advice 和 Advisor 的能力。
    它的实现类 ProxyFactory 是 Spring AOP 主要用于创建 AOP 代理类的核心类。


如果本文对你有所帮助,欢迎点赞收藏!

源码测试工程下载:
老王读Spring IoC源码分析&测试代码下载
老王读Spring AOP源码分析&测试代码下载

公众号后台回复:下载IoC 或者 下载AOP 可以免费下载源码测试工程…

文章,请关注公众号: 老王学源码
gzh


系列博文:
【老王读Spring AOP-0】SpringAop引入&&AOP概念、术语介绍
【老王读Spring AOP-1】Pointcut如何匹配到 join point
【老王读Spring AOP-2】如何为 Pointcut 匹配的类生成动态代理类
【老王读Spring AOP-3】Spring AOP 执行 Pointcut 对应的 Advice 的过程
【老王读Spring AOP-4】Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析
【老王读Spring AOP-5】@Transactional产生AOP代理的原理
【老王读Spring AOP-6】@Async产生AOP代理的原理
【Spring 源码阅读】Spring IoC、AOP 原理小总结

相关阅读:
【Spring源码三千问】Spring动态代理:什么时候使用的 cglib,什么时候使用的是 jdk proxy?
【Spring源码三千问】Advice、Advisor、Advised都是什么接口?
【Spring源码三千问】没有AspectJ,Spring中如何使用SpringAOP、@Transactional?
【Spring源码三千问】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的区别
【Spring 源码三千问】同样是AOP代理bean,为什么@Async标记的bean循环依赖时会报错?


http://chatgpt.dhexx.cn/article/ayAfTGxc.shtml

相关文章

【小家Spring】Spring AOP原理使用的基础类打点(AopInfrastructureBean、ProxyProcessorSupport、Advised、AjType)

每篇一句 没被洪水灌溉过&#xff0c;你怎么能证明这个城市的下水道架构师合理的呢&#xff1f; 相关阅读 【小家Spring】探索Spring AOP中aopalliance的Joinpoint、MethodInvocation、Interceptor、MethodInterceptor… 【小家Spring】Spring AOP原理使用的基础类打点&#x…

Spring AOP名词解释Advice,Pointcut,Advisor,Joinpoint,Advised是什么?

Advice advice解释为通知&#xff0c;需要执行的增强逻辑方法。 advice规范接口如图&#xff0c;分为了before&#xff0c;after等等&#xff0c;为什么没有around呢&#xff0c;因为是通过interceptor实现的。 这里可以看出&#xff0c;AfterAdvice最终会被转换包装成AfterR…

Advised,Advisor,Advice,Pointcut

2019独角兽企业重金招聘Python工程师标准>>> Advised->在Spring中创建了AOP代理之后&#xff0c;就能够使用org.springframework.aop.framework.Advised接口对它们进行管理。 任何AOP代理都能够被转型为这个接口&#xff0c;不论它实现了哪些其它接口 Advisor-&g…

Spring AOP编程官方文档解读之操作Advised对象

Spring AOP编程官方文档解读目录 文章目录 org.springframework.aop.framework.Advised是啥&#xff1f;看一下下面这个类结构图 可以看到无论是ProxyFactoryBean还是ProxyFactory最终都实现了这个接口、这个接口中的方法非常的多&#xff0c;我们随便看一下 public interfac…

arduino知识点梳理(二)——INPUT_PULLUP模式

参考文章1 参考文章2 arduino的引脚模式有三种&#xff1a; INPUT——输入模式OUTPUT——输出模式INPUT_PULLUP——输入上拉模式 Arduino 微控制器自带内部上拉电阻。如果需要使用内部上拉电阻&#xff0c;则应使用pinMode()将引脚设置为输入上拉&#xff08;INPUT_PULLUP&am…

Pull Up Field(字段上移)

两个子类拥有形同的字段 重构&#xff1a;将该字段移至超类

HAL库 output level 和 pull up/ pull down 的区别

从标准库过来的朋友可能对这两个选型有点分不清除 GPIO output level 即输出模式下初始化后端口的电位(高或低) GPIO Pull-up/Pull-down 即输入模式下的电位&#xff0c;例如按键检测

处理概括关系之一 :Pull Up Field(值域上移)

两个subclasses 拥有相同的值域。 将此一值域移至superclass。 动机&#xff08;Motivation&#xff09; 如果各个subclass 是分别开发的&#xff0c;或者是在重构过程中组合起来的&#xff0c;你常会发现它们拥有重复特性&#xff0c;特别是值域更容易重复。这样的值域有时拥有…

Push pull, open drain circuit, pull up, pull down resistor

Push pull 就以下面這個 電路來說&#xff0c; 因為沒有 pull up resistor&#xff0c; 所以 output voltage 由 low 往 high 的速度會較快。有兩個電晶體&#xff0c;一個on&#xff0c;一個 off&#xff0c; 可以 current sourcing&#xff0c;也可以 current sinking&#x…

上拉(Pull Up )或下拉(Pull Down)电阻详解

上拉&#xff08;Pull Up &#xff09;或下拉&#xff08;Pull Down&#xff09;电阻&#xff08;两者统称为“拉电阻”&#xff09;最基本的作用是&#xff1a;将状态不确定的信号线通过一个电阻将其箝位至高电平&#xff08;上拉&#xff09;或低电平&#xff08;下拉&#x…

BetterScroll 2.x 的 pulldown 使用、pullup使用

官方文档&#xff1a;https://better-scroll.github.io/docs/zh-CN/plugins/ BetterScrol滚动原理 有唯一的子节点子节点必须超出包裹的高度new BScroll&#xff08;‘容器名’&#xff09; html内容必须已经渲染完成 绿色部分为 wrapper&#xff0c;也就是父容器&#xff…

【超详细】output level 和 pull up/ pull down 的真正区别

目录 【超详细】output level 和 pull up/ pull down 的真正区别1. Output Level2. Pull up/ Pull down3. 两者的区别1&#xff09;对于Output口来说2&#xff09;而对于Input口来说 总结参考资料 【超详细】output level 和 pull up/ pull down 的真正区别 今天在使用stm32f1…

OUTPUT,INPUT,INPUT_PULLUP三种模式的区别

一&#xff0c;首先三种模式都需要由pinMode()函数来设置。 &#xff08;1&#xff09;设置引脚 为输出&#xff08;OUTPUT&#xff09;模式&#xff0c;此时引脚为低阻抗状态&#xff0c;可以向其他电路原件提供电流&#xff08;通常为40mA以内&#xff09; &#xff08;2&a…

Pull Up Method(函数上移)

动机 避免行为重复是很重要的。尽管重复的两个函数也可以各自工作得很好&#xff0c;但重复自身只会成为错误的滋生地&#xff0c;此外别无价值。无论何时&#xff0c;只要系统之内出现重复&#xff0c;你就会面临“修改其中一个却未能修改另一个”的风险。通常&#xff0c;找…

GPIO_PULLUP,PULLDOWN, NOPULL

NOPULL: 对于输出IO&#xff0c;配置为NOPULL&#xff0c;当IO输出高电平时&#xff0c;IO为1&#xff0c; 当IO输出低电平时&#xff0c;IO为0&#xff1b; PULLUP&#xff1a; 对于输入IO, 默认为高电平&#xff0c;当需要改变为低电平时配置为PULLUP。 比如&#xff1a;K…

pullup和pulldown在verilog中的使用方法

0 前言 这段时间涉及到了IO-PAD&#xff0c;在IO-PAD的RTL的时候注意到了pullup和pulldown&#xff0c;对这个知识比较好奇&#xff0c;就研究了一下&#xff0c;顺便记录下来&#xff0c;IO-PAD的内容等我再研究研究再考虑记录吧 >_< 1 pullup和pulldown的介绍 pullu…

电阻(4)之上拉电阻与下拉电阻详解

原文地址点击这里: 上拉(Pull Up )或下拉(Pull Down)电阻(两者统称为“拉电阻”)最基本的作用是:将状态不确定的信号线通过一个电阻将其箝位至高电平(上拉)或低电平(下拉),无论它的具体用法如何,这个基本的作用都是相同的,只是在不同应用场合中会对电阻的阻值…

解决安装文件时2502、2503错误

在安装文件时有时会出现2502、2503错误&#xff0c;重复安装也不会有什么改变&#xff0c;让人很是头疼。这种问题一般是权限的问题导致的&#xff0c;一般有两种解决办法&#xff0c;第一种就是提升当前用户的权限&#xff0c;第二种就是直接使用CMD安装&#xff0c;这里主要说…

java卸载错误2503_修复控制面板卸载程序时提示错误代码2502、2503的方法

在平常生活中大家是如何卸载软件的呢&#xff1f;有的用户会使用第三方工具&#xff0c;例如软件管家等来进行卸载&#xff0c;这样操作的用户占大多数&#xff0c;但是无法将软件卸载干净。有的用户会直接将安装目录全部删掉&#xff0c;这样操作的用户较少。最理想的卸载软件…

联发科MT2503D处理器详细参数介绍

MT2503D集成了一个ARM7EJ-STM内核&#xff0c;它是运行高级gsm协议软件的主处理器&#xff0c;以及多媒体应用程序、单数字信号处理器核&#xff0c;它管理低层 层次调制解调器和先进的音频功能&#xff0c;嵌入式处理器运行蓝牙基带和链路控制协议和蓝牙无线电控制。 MT 2503…