Spring原理揭秘--初识AOP

我们知道软件开发一直在追求高效,易维护,易扩展的特性方式。在面向过程编程到面向对象编程的历程中,程序的开发有了非常大的进步。但是oop的方式缺依然存在着一些缺点。oop的方式可以将业务进行很好的分解和封装使其模块化,但是却没办法更好的避免类似于系统需求的视线在系统中各处散落这样的问题。比如:不同的主业务可能都会需要一些与业务无关的逻辑代码--日志记录,事务处理等。那么这些相同的无关逻辑在不同业务中的对应关系则会变成1:n的方式。这样就会造成后续维护的成本贼高。因此推出了AOP的方式来对oop的缺点进行优化。

AOP被称为面向方面编程或者切面编程。相当于一个刀直接在业务逻辑上横切。只需要实现AOP的逻辑即可插入到任何的业务逻辑中去从而只需要维护AOP逻辑即可管理所有的非业务逻辑。AOP和OOP是互补的方式而不是竞争的方式。

Java平台上的AOP实现机制

而在java平台上实现AOP的方式有以下几种

动态代理:

JDK1.3之后引入了动态代理的机制,可以在运行期间,为相应的接口动态生成代理对象。所以,我们可以将横切关注点逻辑封装到动态代理的InvocationHandler当中,然后在运行期间通过动态代理生成对应对象的子类将横切逻辑织入到代理对象当中。这种方式相比于静态代理则是性能稍微逊色一些。同时有一个缺点就是只能实现接口的动态代理,那些没有接口实现的类则无法实现动态代理

动态字节码增强:

java虚拟机加载的class文件都是符合一定的规范的,所以只要交给java虚拟机运行的class文件符合java class规范那么程序运行就没有什么问题。而通常情况下class文件是通过java编译期编译而形成的。而java则推出了CGLIB的方式等java工具库,在运行期间通过修改字节码的方式来实现动态增强,将新增的业务逻辑加入到AOP逻辑当中。CJLIB的方式则不需要java类去继承接口,只需要java类能够生成子类即可就能实现动态字节码增强

AOP的各个组件

Joinpoint:

在系统运行之前,aop的功能就需要织入到OOP当中,所以这个注入的过程我们需要知道在OOP代码中哪些执行点上进行织入操作,这些将要在其之上进行织入操作的系统执行点就是Joinpoint

比如上述的代码执行流程图当中我们可以在以下阶段进行织入:

方法调用:当某个方法被调用的时候所处的程序执行点,图中的三个圆圈则是属于这种类型。

方法调用执行:这种方式的本质是在执行,也就是在方法体内执行的时候才会调用。与方法调用的区别在于一般方法调用先执行而方法调用执行后执行

构造方法调用:与方法调用意思几乎相同,在构造方法进行初始化的时候进行执行

构造方法调用执行:则是在执行构造方法的时候才会真正的执行

字段设置:在设置某个属性通过setter方法被设置或者直接被设置的时点。该Joinpoint的本质是对象属性被设置时候触发

字段获取:在获取相对字段的时候也就是通过getter方法访问或者直接访问的时候则会触发

异常处理执行:当出现异常的时候,则会在对应的异常抛出点执行

类初始化:类初始化则是类中某些静态类型或者静态代码块初始化的时间点上的时候会执行

基本上在代码执行的过程中所有的执行时点上都可以作为Joinpoint,那么这些joinpoint有了如果我们仅仅在需要的地方执行如何告诉程序呢?

Poincut

Poincut则是告诉程序需要在哪些Joinpoint上去执行AOP逻辑处理,如果说Joinpoint是所有的可执行点,那么Poincut则是真正需要执行AOP的执行点。

在 Spring AOP 中,Pointcut 主要通过以下方式实现:

1. 基于注解的 Pointcut

使用 @Pointcut 注解定义切入点表达式,常见的表达式类型包括:

  • execution:匹配方法执行连接点。
  • within:匹配指定类型内的方法。
  • @annotation:匹配带有特定注解的方法。

2. execution 表达式

最常用的表达式类型,语法为:

execution(修饰符? 返回类型 类路径?方法名(参数) throws 异常?)

2. 其他表达式类型

  • within:限制匹配范围为特定类型。

// 匹配 UserService 类中的所有方法
within(com.example.service.UserService)// 匹配 service 包下的所有类的方法
within(com.example.service.*)// 匹配 service 包及其子包下的所有类的方法
within(com.example.service..*)
  • @annotation:匹配带有特定注解的方法。

// 匹配所有带 @Loggable 注解的方法
@annotation(com.example.annotation.Loggable)

2. 基于 XML 配置的 Pointcut

在 Spring XML 配置中,可以使用 <aop:pointcut> 元素定义切入点

Pointcut 本身只是定义筛选条件,需要与通知(Advice) 结合才能实现 AOP 的增强功能

💡 黄金法则
Pointcut = 在哪里切(Where) + 切什么(What)
好的切点表达式应该像精准的手术刀,而非大锤。

Adivce

Advice(通知) 是核心概念之一,用于定义在目标方法执行的特定时机插入的横切逻辑(如日志、事务、权限校验等)。它决定了切面(Aspect)行为的具体执行位置和内容。

以下是Spring AOP支持的Advice类型及其执行时机:

通知类型注解执行时机
Before Advice@Before在目标方法执行前触发(例如:权限校验)
After Returning@AfterReturning在目标方法成功返回后触发(例如:记录操作结果)
After Throwing@AfterThrowing在目标方法抛出异常后触发(例如:异常日志记录)
After (Finally)@After在目标方法结束后触发(无论成功/异常,类似finally块,例如:资源清理)
Around Advice@Around环绕目标方法执行,可控制方法调用、修改参数/返回值(例如:性能监控、事务管理)

Advice 是 Spring AOP 实现横切逻辑的核心机制,通过五种类型覆盖方法执行的各个生命周期节点,显著提升代码复用性和可维护性。正确使用Advice能高效解决日志、事务、安全等横切关注点问题,是Spring生态中不可或缺的组件。

织入和织入器

织入 是指将 切面(Aspect) 中定义的横切逻辑(Advice)动态植入到目标对象(Target Object) 的过程。类比织布,就是将切面的"线"编织到业务逻辑的"布料"中。

关键作用:

  1. 动态增强目标对象
    在目标方法执行的特定位置(如方法调用前、返回后、异常时)插入横切逻辑(如日志、事务等)。

  2. 实现逻辑解耦
    将核心业务逻辑(如用户服务)与非功能性需求(如日志记录)分离,通过织入机制在运行时组合。

  3. 支持多种植入方式

织入时机实现方式特点
编译时织入使用 AspectJ 编译器性能高,但需要特殊编译步骤(如 Maven 插件)
类加载时织入通过 Java Agent(LTW)无需修改源码,在 JVM 加载类时植入(Spring 支持)
运行时织入Spring AOP 默认方式(动态代理)无需编译支持,但仅作用于 Spring 容器管理的 Bean(最常用)

织入器 是负责执行织入操作的底层引擎。在 Spring AOP 中,织入器由框架内部实现,开发者通过配置驱动其工作。

核心职责:
  1. 解析切面配置
    读取 @Aspect 注解或 XML 配置,识别 Pointcut(切入点)和 Advice(通知)的定义。

  2. 匹配连接点(Join Point)
    根据 Pointcut 表达式(如 execution(* com.service.*.*(..)))定位需要增强的目标方法。

  3. 生成代理对象

    代理类型触发条件实现方式
    JDK 动态代理目标类实现了接口基于 java.lang.reflect.Proxy
    CGLIB 代理目标类未实现接口(或强制使用)通过字节码生成子类(如 UserService$$EnhancerBySpringCGLIB
  4. 植入 Advice 逻辑
    在代理对象中按顺序集成各类通知(如 @Before@Around),构建执行链。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/bicheng/88984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Provider模式:软件架构中的“供应商“设计哲学

文章目录Provider模式&#xff1a;软件架构中的“供应商“设计哲学什么是Provider模式&#xff1f;经典应用场景1. 配置管理Provider2. 数据访问Provider4. 消息队列ProviderProvider模式的优势1. 解耦合实际项目中的应用Provider模式的最佳实践1. 命名约定2. 接口设计原则3. 错…

LTspic下载,帮助及演示电路

1.下载 LTspice是一款强大高效的免费SPICE仿真器软件、原理图采集和波形观测器&#xff0c;为改善模拟电路的仿真提供增强功能和模型。其原理图捕获图形界面使您能够探测原理图并生成仿真结果&#xff0c;这些结果可以通过内置波形查看器进一步观察分析。 链接&#xff1a; …

位置编码/绝对位置编码/相对位置编码/Rope原理+公式详细推导及代码实现

文章目录1. 位置编码概述1.1 为什么需要位置编码&#xff1f;2. 绝对位置编码 (Absolute Position Encoding)2.1 原理2.2 数学公式2.3 代码实现2.4 代码与公式的对应关系2.5 特性与优势2.6 可学习的绝对位置编码3. 相对位置编码 (Relative Position Encoding)3.1 原理3.2 数学公…

网络安全初级第一次作业

一&#xff0c;docker搭建和挂载vpm 1.安装 Docker apt-get install docker.io docker-compose 2.创建文件 mkdir /etc/docker.service.d vim /etc/docker.service.d/http-proxy.conf 3.改写文件配置 [Service] Environment"HTTP_PROXYhttp://192.168.10.103:7890…

交换类排序的C语言实现

交换类排序包括冒泡排序和快速排序两种。冒泡排序基本介绍冒泡排序是通过重复比较相邻元素并交换位置实现排序。其核心思想是每一轮遍历将未排序序列中的最大&#xff08;或最小&#xff09;元素"浮动"到正确位置&#xff0c;类似气泡上升。基本过程是从序列起始位置…

嵌入式 Linux开发环境构建之Source Insight 的安装和使用

目录 一、Source Insight 的安装 二、Source Insight 使用 一、Source Insight 的安装 这个软件是代码编辑和查看软件&#xff0c;打开开发板光盘软件&#xff0c;然后右键选择以管理员身份运行这个安装包。在弹出来的安装向导里面点击 next &#xff0c;如下图所示。这里选择…

【字节跳动】数据挖掘面试题0016:解释AUC的定义,它解决了什么问题,优缺点是什么,并说出工业界如何计算AUC。

文章大纲 AUC(Area Under the Curve)详解一、定义:AUC是什么?二、解决了什么问题?三、优缺点分析四、工业界大规模计算AUC的方法1. 标准计算(小数据)2. 工业级大规模计算方案3.工业界最佳实践4.工业界方案选型建议总结:AUC的本质AUC(Area Under the Curve)详解 一、…

Python后端项目之:我为什么使用pdm+uv

在试用了一段时间的uv和pdm之后&#xff0c;上个月(2025.06)开始&#xff0c;逐步把用了几年的poetry替换成了pdmuv&#xff08;pipx install pdm uv && pdm config use_uv true) ## 为什么poetry -> pdm: 1. 通过ssh连接到服务器并使用poetry shell激活虚拟环境之…

鸿蒙Next开发,配置Navigation的Route

1. 通过router_map.json配置文件进行 创建页面配置router_map.json {"routerMap": [{"name": "StateExamplePage","pageSourceFile": "src/main/ets/pages/state/StateExamplePage.ets","buildFunction": "P…

在 GitHub 上创建私有仓库

一、在 GitHub 上创建私有仓库打开 GitHub官网 并登录。点击右上角的 “” → 选择 “New repository”。填写以下内容&#xff1a; Repository name&#xff1a;仓库名称&#xff0c;例如 my-private-repo。Description&#xff1a;可选&#xff0c;仓库描述。Visibility&…

量产技巧之RK3588 Android12默认移除导航栏状态栏​

本文介绍使用源码编译默认去掉导航栏/状态栏方法,以触觉智能EVB3588开发板演示&#xff0c;Android12系统&#xff0c;搭载了瑞芯微RK3588芯片&#xff0c;该开发板是核心板加底板设计&#xff0c;音视频接口、通信接口等各类接口一应俱全&#xff0c;可帮助企业提高产品开发效…

Conda 安装与配置详解及常见问题解决

《Conda 安装与配置详解及常见问题解决》 安装 Conda 有两种主流方式&#xff0c;分别是安装 Miniconda&#xff08;轻量级&#xff09;和 Anaconda&#xff08;包含常用数据科学包&#xff09;。下面为你详细介绍安装步骤和注意要点。 一、安装 Miniconda&#xff08;推荐&a…

Linux ——lastb定时备份清理

lastb 命令显示的是系统中 /var/log/btmp 文件中的SSH 登录失败记录。你可以像处理 wtmp 那样&#xff0c;对 btmp 文件进行备份与清理。✅ 一、备份 lastb 数据cp /var/log/btmp /var/log/btmp.backup.$(date %F)会保存为如 /var/log/btmp.backup.2025-07-14✅ 二、清空 lastb…

自定义类型 - 联合体与枚举(百度笔试题算法优化)

目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员的结构体和联合体对比1.4 联合体大小的计算1.5 联合练习二、枚举类型2.1 枚举类型的声明2.2 枚举类型的优点总结一、联合体 1.1 联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成…

FS820R08A6P2LB——英飞凌高性能IGBT模块,驱动高效能源未来!

产品概述FS820R08A6P2LB 是英飞凌&#xff08;Infineon&#xff09;推出的一款高性能、高可靠性IGBT功率模块&#xff0c;采用先进的EconoDUAL™ 3封装&#xff0c;专为大功率工业应用设计。该模块集成了IGBT&#xff08;绝缘栅双极型晶体管&#xff09;和二极管&#xff0c;适…

python学智能算法(十八)|SVM基础概念-向量点积

引言 前序学习进程中&#xff0c;已经对向量的基础定义有所了解&#xff0c;已经知晓了向量的值和方向向量的定义&#xff0c;学习链接如下&#xff1a; 向量的值和方向 在此基础上&#xff0c;本文进一步学习向量点积。 向量点积 向量点积运算规则&#xff0c;我们在中学阶…

【windows办公小助手】比文档编辑器更好用的Notepad++轻量编辑器

Notepad 中文版软件下载&#xff1a;这个路径总是显示有百度无法下载&#xff0c;不推荐 更新&#xff1a;推荐下载路径 https://github.com/notepad-plus-plus/notepad-plus-plus/releases 参考博主&#xff1a;Notepad的安装与使用

2025年7月12日全国青少年信息素养大赛图形化(Scratch)编程小学高年级组复赛真题+答案解析

2025年7月12日全国青少年信息素养大赛图形化(Scratch)编程小学高年级组复赛真题+答案解析 选择题 题目一 运行如图所示的程序,舞台上一共会出现多少只小猫呢?( ) A. 5 B. 6 C. 7 D. 8 正确答案: B 答案解析: 程序中“当绿旗被点击”后,角色先移到指定位置,然后“重…

对于独热编码余弦相似度结果为0和词向量解决了词之间相似性问题的理解

文章目录深入理解简单案例结论词向量&#xff08;Word Embedding&#xff09;简介词向量如何解决相似性问题&#xff1f;简单案例&#xff1a;基于上下文的词向量训练总结对于独热表示的向量&#xff0c;如果采用余弦相似度计算向量间的相似度&#xff0c;可以明显的发现任意两…

数据结构·数状数组(BIT)

树状数组(Binary Index Tree) 英文名&#xff1a;使用二进制下标的树结构 理解&#xff1a;这个树实际上用数组来存&#xff0c;二进制下标就是将正常的下标拆为二进制来看。 求x的最低位1的函数lowbit&#xff08;x&#xff09; 假设x的二进制表示为x ...10000&#xff0c;…