Spring之AOP底层原理

在Spring中创建切面类只需添加@Aspect注解,并定义增强方法。AOP通过DefaultAutoProxyCreator进行方法增强,当bean初始化后,会根据条件创建JdkProxy或Cglib代理对象。JdkProxy适用于有接口的bean,而Cglib则通过ASM动态生成字节码实现无接口bean的代理。
摘要由CSDN通过智能技术生成

如何创建一个切面类

只需要新建一个类,为它增加AOP切面注解@Aspect就可以使用了。

在里面定义一些“增强方法”,然后通过@Before@After@AfterReturningAfterThrowing@Round注解来指定何时执行方法的增强。

分别表示在方法之前、在方法之后、在方法正常返回后、在方法异常返回后、对方法进行包裹。

在这里插入图片描述
这里是一个@After的实例,这里的@After就等于@AfterReturning加上@AfterThrowing。在这5个注解中使用execution表达式进行增强范围的限定,可以精确到某些类的某些方法,写了这几个简单的注解之后,Spring的AOP就生效了。

在这里插入图片描述
运行原本的Bean方法,就会在方法执行之后触发编写的增强方法。

AOP具体如何在Spring中运行

在Spring启动的时候会创建IOC容器,同时将Spring中的bean进行三个连续的动作——构造填充属性初始化

在这里插入图片描述
AOP功能就是通过Spring中一个专门处理AOP的“bean后置处理器”DefaultAutoProxyCreator进行方法增强的,可以算作IOC器官的附加功能。

所有的后置处理器都在bean构造完并且填充了属性之后执行,当然也包括我们的AOP后置处理器。

在每个Bean初始化之后,都会调用这个后置处理器的postProcessAfterInitialization方法:

在这里插入图片描述
在这个方法里,Spring会为需要使用AOP的bean创建代理对象。

先通过getAdvicesAndAdvisorsForBean方法获取所有的增强Advice。同时判断当前bean是否满足我们配置的切面条件。

在这里插入图片描述
如果满足条件的话,就会为这个bean构造“代理对象”来实现AOP。

在这里插入图片描述
为了更统一、更方便地构造代理对象,Spring会先搭建一个专门用来构造生产代理对象的工厂proxyFactory,Spring会告诉这个工厂具体选择哪种方式进行代理,分别是JdkProxyCglib

在这里插入图片描述
程序员可以通过添加@EnableAspectJAutoProxy注解,并且将其中proxyTargetClass配置改为true,来强制使用Cglib。

在SpringBoot中默认使用的就是Cglib。不过,只有这个配置为false,同时该类实现了任意接口,才会使用JdkProxy,否则还是会使用Cglib方式。

proxyfactory知道使用哪种方式之后就会构造JdkDynamicAopProxy或者CglibAopProxy,然后就可以通过它们的getProxy方法获得真正的代理对象。

JdkProxy

在这里插入图片描述
先说相对简单而且即将被Spring无情放弃的JdkDynamicAopProxy。

在这里插入图片描述
在getProxy中会构造一个实现同样bean接口的代理对象,将真实bean作为代理对象中的一个成员变量。在调用bean方法的时候,就会执行代理对象中的invoke方法,这个invoke方法只有两步:

  1. 第一步,Spring会通过之前提到的“execution表达式”获取所有与该方法匹配的所有“增强方法”,并将它们组成调用链,同时进行排序
  2. 第二步,就是开始按顺序执行这些调用链,这里的调用方式就是经典的“责任链模式”,在调用中间会插入并执行bean真实的方法。

Cglib

在这里插入图片描述

然后是最为常用的CglibAopProxy,同样会在getProxy方法中构造代理对象。用增强器Enhancer来设置代理基本信息以及增强方法的调用链。

接着执行Enhancer的create()方法来生成代理对象,和jdkDynamicAopProxy不同的是Cglib是基于jdk rt jar包中的ASM来生成一组新的.class文件,然后实例化它的对象。所以对于没有实现接口的bean也可以生成代理对象。

在调用bean方法时候会先执行代理对象的intercept方法,与jdkProxy一样也会通过责任链来执行所有的方法增强

参考资料史上最完整的AOP底层原理

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP (Aspect Oriented Programming) 是 Spring 框架中的一个模块,它实现了面向切面编程,允许开发者将横切关注点(如事务管理、日志记录、安全检查等)抽取到独立的模块中,从而避免代码重复和提高模块的可维护性。Spring AOP底层原理主要基于以下几个关键概念: 1. **通知(Advice)**: 是 AOP 的核心,它是对目标方法执行前后的行为进行增强的代码片段。Spring 提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回后通知(AfterReturning)、异常通知(AfterThrowing)和最终通知(Around)。 2. **切点(Pointcut)**: 定义了一组相关的通知应该何时何地应用。Spring 使用表达式语言(如`@annotation`, `@execution`, `@target`, `@within`等)来定义切点,匹配方法执行的条件。 3. **连接点(Join Point)**: 是程序执行过程中的一点,是通知被应用的地方。Spring AOP 检查通知的匹配条件并在合适的时候执行。 4. **代理(AOP Proxy)**: Spring AOP 实现了一种特殊的代理机制,为被拦截的目标对象创建一个代理对象。有两种代理模式:JDK 动态代理和 CGLIB 生成的字节码代理。对于接口,使用 JDK 动态代理;对于类,如果目标类没有实现接口或没有 final 方法,使用 CGLIB。 5. **切面(Angle)**: 是一组相关通知的集合,由切点和通知组成。在 Spring 中,切面通过 `@Aspect` 注解声明,`@AspectJ` 是其底层语法支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值