当前位置: 首页 > news >正文

Spring Boot 自动配置之 Spring‘s AOP

几句话理解 Spring's AOP 

  1. 基于 代理(JDK Proxy / CGLIB)的运行时增强 AOP 实现;
  2. 默认只拦截 Spring 容器管理的 Bean 的 public 方法;
  3. 不需要 AspectJ 的编译器或 weaver,Spring 只是借用了 AspectJ 的 注解风格(@Aspect, @Pointcut, @Before, @After 等),但默认并没有用 AspectJ 的编译器或织入器

拦截原理和时机

  • 容器启动阶段

    • Spring 在 Bean 初始化阶段(BeanPostProcessor 阶段),通过 AnnotationAwareAspectJAutoProxyCreator 扫描切面类。

    • 对匹配切点的 Bean,Spring 会用代理对象替换原始 Bean。

  • 运行时调用阶段

    • 当客户端(例如 Controller 或其他 Bean)调用目标 Bean 的方法时,实际上调用的是代理对象的方法。

    • 代理对象会在 方法执行前执行后抛出异常时环绕执行 时,织入切面逻辑。

  • 限制

    • Spring AOP 只能拦截 Spring 容器管理的 Bean

    • 默认只支持 方法级别的 Join Point(不像 AspectJ 可以拦截构造函数、字段访问等)。

    • 自调用(同一个类内部方法互调)不会触发代理,因此不会被 AOP 拦截。

自动配置类 AopAutoConfiguration

包:org.springframework.boot.autoconfigure.aop

类:AopAutoConfiguration

package org.springframework.boot.autoconfigure.aop;import org.aspectj.weaver.Advice;import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@AutoConfiguration
@ConditionalOnBooleanProperty(name = "spring.aop.auto", matchIfMissing = true)
public class AopAutoConfiguration {@Configuration(proxyBeanMethods = false)@ConditionalOnClass(Advice.class)static class AspectJAutoProxyingConfiguration {@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", havingValue = false)static class JdkDynamicAutoProxyConfiguration {}@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)static class CglibAutoProxyConfiguration {}}@Configuration(proxyBeanMethods = false)@ConditionalOnMissingClass("org.aspectj.weaver.Advice")@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)static class ClassProxyingConfiguration {@Beanstatic BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {return (beanFactory) -> {if (beanFactory instanceof BeanDefinitionRegistry registry) {AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}};}}}

以上是 Spring AOP 自动配置类的完整代码,下面拆开来分析。

@ConditionalOnBooleanProperty(name = "spring.aop.auto", matchIfMissing = true)

自动配置类的生效的先决条件 :"spring.aop.auto"  这个属性值必须为 "true" (默认值,属性缺失时默认为 true),也就是说 Spring AOP 的功能是默认自动开启的

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", havingValue = false)static class JdkDynamicAutoProxyConfiguration {}@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)static class CglibAutoProxyConfiguration {}}

classpath 上有 AspectJ 的 API

@ConditionalOnClass(Advice.class)

@ConditionalOnClass(Advice.class) 的作用就是:确保 classpath 上有 AspectJ 的 API(至少有 weaver 包),Spring 才能正确解析 @Aspect 注解和切点表达式。一旦缺少这些类,Spring Boot 就不会启用 AspectJAutoProxyingConfiguration,避免报错。

@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", havingValue = false)

如果属性 “spring.aop.proxy-target-class” 的值为 “false”,则使用 JDK 代理;

	@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)

如果属性 “spring.aop.proxy-target-class” 的值为 “tue” 或 缺失没有配置(缺失时默认为 true),则使用 CGLIB 代理。

classpath 上 AspectJ 的 API

 @ConditionalOnMissingClass("org.aspectj.weaver.Advice")

	@Configuration(proxyBeanMethods = false)@ConditionalOnMissingClass("org.aspectj.weaver.Advice")@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)static class ClassProxyingConfiguration {@Beanstatic BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {return (beanFactory) -> {if (beanFactory instanceof BeanDefinitionRegistry registry) {AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}};}}

如果 classpath 上无 AspectJ 的 API,并且 "spring.aop.proxy-target-class" 属性值没有明确设置为 “false”,则 Spring AOP 强制使用 CGLIB 代理。

总结:

如果 org.aspectj.weaver.Advice 存在 且 spring.aop.proxy-target-class=false,Spring Boot 就会自动使用 JDK 动态代理,否则就会使用 CGLIB 代理;且无须手动开启 @EnableAspectJAutoProxy 注解。

如果 org.aspectj.weaver.Advice 不存在且 spring.aop.proxy-target-class=false 时 Spring Boot 的自动 AOP 配置不会生效,换句话说:Spring Boot 不会自动开启基于注解的 AOP

如果 org.aspectj.weaver.Advice 不存在且 spring.aop.proxy-target-class=true (默认值)时 Spring Boot 强制使用 CGLIB 代理;这是 Spring Boot AOP 自动配置的“兜底方案”,确保在没有 AspectJ 时,依然能用 CGLIB 代理来启用 AOP;即使没有引入 AspectJ weaver(即没有 org.aspectj.weaver.Advice),Spring Boot 在兜底方案下依然能让你使用 @Aspect 注解来定义切面。

http://www.dtcms.com/a/418871.html

相关文章:

  • 基于单片机的直流电机控制系统(论文+源码)
  • 步进电机上电瞬间异常微动分析与常见类似问题解析
  • cms网站是什么怎么建好网站
  • 网站后台帐号密码破解贵阳网站设计报价
  • FFmpeg过滤器实战:混音
  • docker desktop镜像无法加载问题
  • CrashHandler 崩溃处理工具类(兼容 Android 16+ / API 16)捕获未处理异常、本地存储崩溃日志、上传日志到服务器
  • K8s学习----节点(Node)
  • 网站常用文件夹网站建设 月嫂 模板
  • 做整合营销的网站天津网站制作专业
  • gitlab定时备份
  • 企业网站源码怎么获取html家乡网页完整代码
  • 郑州市东区建设环保局官方网站手机怎么搭建属于自己的网站
  • display ip routing-table [ip-address] 概念及题目
  • Unity 单元测试框架用法
  • JavaWeb 课堂笔记 —— 21 登录认证
  • 凤岗网站设计云南哪里可以制作自己的网页
  • Kafka07-集成-尚硅谷
  • Windows 11 WSL2 迁移到非系统盘(E 盘)教程
  • 逻辑回归与神经网络:本质联系与核心区别
  • 哈尔滨建站在线咨询龙之网官网
  • 顺德做营销网站公司wordpress 会员 按月
  • 微程序控制器
  • 零基础学AI大模型之Prompt提示词工程
  • mysql基础【基础概念与数据模型】
  • Windows系统Web UI自动化测试学习系列4--开源系统平台测试项目环境部署搭建
  • 深入理解 C++ 中的 `std::bind`:功能、用法与实践
  • 具有营销型网站有哪些长沙市建设局网站
  • 对于网站建设的提问海陵区建设局网站
  • QML学习笔记(十七)QML的属性变更信号