Spring 框架的核心基础:IoC 和 AOP
一、IoC(Inversion of Control,控制反转)
定义:
IoC(Inversion of Control,控制反转),就是把对象创建和依赖关系的管理交给 Spring 容器,而不是由程序员手动去创建对象和管理依赖。
IoC 以前是我们想要什么就自己创建什么,现在是我们需要什么容器就帮我们送来什么。
举例:
以前:
UserService userService = new UserServiceImpl();
现在:
@Autowired
UserService userService;
Spring 帮忙创建并注入了这个对象,这就叫 控制反转(IoC)。
Spring 倡导的开发方式就是这样,所有类的创建和销毁都通过 Spring 容器来,不再是开发者去 new,去 = null
,这样就实现了对象的解耦。
于是,对于某个对象来说,以前是它控制它依赖的对象,现在是所有对象都被 Spring 控制。
说说什么是 DI?
定义:
IoC 是一种思想,DI 是实现 IoC 的具体方式,将一个对象所依赖的其他对象 以参数的形式传入,由外部容器(如 Spring)来“注入”依赖,而不是对象自己创建。
打个比方,你现在想吃炒菜和饭,点个外卖这时候就有人把炒好的菜和煮好的饭送到你手上。就好像 A 类需要 B 类,以前是 A 类自己 new 一个 B 类,现在是有人把 B 类送给到 A 类里。
常见方式:
- 构造方法注入
- Setter 方法注入
- 字段注入(推荐使用构造注入)
举例(构造注入):
@Service
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}
}
Spring 会自动将 UserRepository
注入。
为什么要使用 IoC 呢?
- 解耦:让对象的创建和管理交给 Spring 容器,降低对象之间的耦合度。
- 提高可维护性:对象的依赖关系由 Spring 统一管理,方便修改和扩展。
总结
IoC(Inversion of Control)
指的是控制反转,将对象创建和依赖关系都交给 Spring 容器去做;DI(Dependency Injection)
指的是依赖注入,是 IoC 的具体实现方式,包括构造方法、setter 方法和注解方式注入;使用IoC 是为了降低对象间的耦合度和方便修改和扩展。
Spring IoC 容器运行机制的核心之一:Bean 的生命周期
完整生命周期流程图分为五个阶段:
- 实例化:Spring 首先使用构造方法或者工厂方法创建一个 Bean 的实例。在这个阶段,Bean 还没有被依赖注入。
- 属性赋值:Spring 根据配置文件,将所有所需的属性值或依赖的 Bean 注入到该 Bean 中。这个过程称为依赖注入。
- 初始化:在 Bean 依赖注入完成后,Spring 允许 Bean 进行初始化,可以在这里执行一些启动逻辑。(Spring 调用 afterPropertiesSet 方法,或通过配置文件指定的 init-method 方法,完成初始化。)
- 使用中:Bean 准备好可以使用了。
- 销毁:在容器关闭时,Spring 会调用 destroy 方法,完成 Bean 的清理工作。
实例化↓
属性赋值(依赖注入)↓
调用 BeanNameAware / BeanFactoryAware 等↓
调用初始化方法(如 @PostConstruct、afterPropertiesSet())↓
Bean 准备就绪,可被使用↓
容器关闭前调用销毁方法(如 @PreDestroy、destroy())
从源码角度来讲:
- 实例化:Spring 容器根据 Bean 的定义创建 Bean 的实例,相当于执行构造方法,也就是 new 一个对象。
- 属性赋值:相当于执行 setter 方法为字段赋值。
- 初始化:初始化阶段允许执行自定义的逻辑,比如设置某些必要的属性值、开启资源、执行预加载操作等,以确保 Bean 在使用之前是完全配置好的。
- 销毁:相当于执行
= null
,释放资源。
可以在源码 AbstractAutowireCapableBeanFactory
中的 doCreateBean
方法中,看到 Bean 的前三个生命周期:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 实例化阶段instanceWrapper = this.createBeanInstance(beanName, mbd, args);}...Object exposedObject = bean;try {// 属性赋值阶段this.populateBean(beanName, mbd, instanceWrapper);// 初始化阶段exposedObject = this.initializeBean(beanName, exposedObject, mbd);} catch (Throwable var18) {...}...
}
源码位置,见下图:
至于销毁,是在容器关闭的时候调用的,详见 ConfigurableApplicationContext
的 close
方法。
二、AOP(Aspect-Oriented Programming,面向切面编程)
定义:
AOP,也就是面向切面编程,将业务逻辑中一些 通用的功能逻辑(如日志、事务、权限)从业务逻辑中抽离,统一切入到一个独立的模块中,让业务逻辑更加清爽,提高代码复用性和解耦性。
核心概念:
名称 | 含义 |
---|---|
JoinPoint | 程序执行的某个点,如方法调用 |
Pointcut | 切入点,匹配 JoinPoint 的规则 |
Advice | 要执行的逻辑,如 before/after/around |
Aspect | 切面,通知和切入点的组合 |
Weaving | 将切面织入到目标对象的过程 |
举例:
场景:给 Service 方法统一加上日志
我们有一个 UserService
,每次调用它的方法前都想打印日志,比如:
[Log] 正在调用方法:getUserById
1、创建业务类
@Service
public class UserService {public String getUserById(Long id) {System.out.println("正在执行 getUserById 业务逻辑");return "用户ID:" + id;}
}
2、创建切面类(日志功能)
@Aspect
@Component
public class LogAspect {// 切点:拦截所有 UserService 的方法@Pointcut("execution(* com.example.service.UserService.*(..))")public void userServiceMethods() {}// 前置通知:方法执行前打印日志@Before("userServiceMethods()")public void logBefore(JoinPoint joinPoint) {String method = joinPoint.getSignature().getName();System.out.println("[Log] 正在调用方法:" + method);}// 后置通知:方法执行完后打印@AfterReturning(pointcut = "userServiceMethods()", returning = "result")public void logAfter(JoinPoint joinPoint, Object result) {System.out.println("[Log] 方法执行完成,返回结果:" + result);}
}
3、开启 AOP 功能(Spring Boot 自动开启)
确保 Spring Boot 项目中依赖了 spring-boot-starter-aop
:
<!-- pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
4、运行效果
调用如下代码:
@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/user/{id}")public String getUser(@PathVariable Long id) {return userService.getUserById(id);}
}
控制台输出:
[Log] 正在调用方法:getUserById
正在执行 getUserById 业务逻辑
[Log] 方法执行完成,返回结果:用户ID:123
总结一句话:
AOP 是在 不改动源码的情况下 给程序添加额外功能(日志、事务、监控等)。
IoC、DI、AOP 对比:
概念 | 一句话解释 |
---|---|
IoC | 把对象的创建和管理交给 Spring 容器 |
DI | Spring 容器负责把依赖“注入”到类中 |
AOP | 给程序动态添加功能,而不改动源码 |
相关文章:
Spring 框架的核心基础:IoC 和 AOP
一、IoC(Inversion of Control,控制反转) 定义: IoC(Inversion of Control,控制反转),就是把对象创建和依赖关系的管理交给 Spring 容器,而不是由程序员手动去创建对象…...
JavaScript逆向工程实战:如何精准定位加密参数生成位置
前言:一个令人困惑的调试案例 最近在进行某网站的JavaScript逆向分析时,我遇到了一个有趣的现象:当我尝试定位一个名为m的加密参数(值为MTIwMTE3NDQxODk1NTY1NjkA这样的Base64字符串)时,调试器却带我来到了…...
SSM智能停车场管理系统
🍅点赞收藏关注 → 添加文档最下方联系方式咨询本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅 项目视频 SS…...
[定位器]晶艺LA1823,4.5V~100V, 3.5A,替换MP9487,MP9486A,启烨科技
Features 4.5V to 100V Wide Input Range 3.5A Typical Peak Current Limit Integrated 500mΩ low resistance high side power MOS. Constant On Time Control with Constant Switching Frequency. 180μA Low Quiescent Current 150kHz/240kHz/420kHz Swi…...
天元证券|A股大反攻!北证50涨超10%!芯片股大爆发
今日,A股全线走强。 科技成长股领涨,北证50指数飙升逾10%,科创50也大涨超4%,深证成指、上证指数午后也稳步拉升涨逾1%。值得注意的是,上证50指数临近收盘集合竞价的时候直线拉升。近4600只个股上涨,成交稳步…...
利用python从零实现Byte Pair Encoding(BPE):NLP 中的“变形金刚”
BPE:NLP 界的“变形金刚”,从零开始的奇幻之旅 在自然语言处理(NLP)的世界里,有一个古老而神秘的传说,讲述着一种强大的魔法——Byte Pair Encoding(BPE)。它能够将普通的文本“变形…...
最新Web系统全面测试指南
你有没有遇到过这样的情况: 系统上线当天,用户频频报错,运维一脸懵逼,开发说“我本地没问题”? 你明明写了几十个测试用例,结果却还是有 Bug 漏网? Web 系统测试,不只是点点点&#…...
OpenBMC:BmcWeb 处理http请求6 调用路由处理函数
OpenBMC:BmcWeb 处理http请求5 检查权限-CSDN博客 检查完权限后,调用了rule.handle(*req, asyncResp, params); template <typename... Args> class TaggedRule :public BaseRule,public RuleParameterTraits<TaggedRule<Args...>> {void handle(const Req…...
售货机管理系统:智慧零售时代的运营新引擎
一、引言 在快节奏的都市生活中,自动售货机已成为便捷消费的重要场景。然而,传统售货机依赖人工补货、手工对账,常面临库存失衡、设备故障发现滞后、数据孤岛等痛点。如何突破效率瓶颈?本文将深入剖析榕壹云售货机管理系统的项目背景、客户定位、技术与核心功能、系统优势…...
Python基础全解析:从输入输出到字符编码的深度探索
一、Python程序交互的基石:Print函数详解 1.1 基础输出功能 # 输出数字 print(20.5) # 输出浮点数:20.5 print(0b0010) # 输出二进制数:10# 输出字符串 print(Hello World!) # 经典输出示例# 表达式计算 print(4 4 * (2-1)…...
Python第八章02:数据可视化Pyecharts包无法使用
PS:本节纯属个人在学习过程中遇到问题、解决问题的经验分享,对学习进度没影响,没有遇到该问题的小伙伴可跳过。 首先,在学习数据图形化过程中,通过命令提示符安装了Pyecharts包,在命令提示符中验证安装成功。 在PyChar…...
【人工智能】如何通过精准提示工程实现完美的珠宝首饰展示
AI艺术创作指南:如何通过精准提示工程实现完美的珠宝首饰展示 引言:认知边界的突破 在AI艺术创作的漫长探索中,许多创作者面临着相似的困扰:当他们看到别人能够通过算法编织出如同文艺复兴时期细腻油画般的奢华珠宝展示图&#…...
Redis学习总结(持续更新)
Redis 目前在学习redis,遇到的一些问题会放在这里,加深自己的印象。 1. Redis缓存相较于传统Session存储的特点 Session的存储方式: 通常,传统的Session是存储在应用服务器的内存中,比如Tomcat的Session管理器。用户…...
RabbitMQ从入门到实战-3(高可靠性)
文章目录 发送者可靠性发送者重连发送者确认(一般不会开启)指定returncallback和confrimfallbacktips MQ可靠性数据持久化LazyQueue(默认模式且不可更改) 消费者的可靠性消费者确认机制消费者失败重试业务幂等性唯一消息id业务判断…...
RTK 实时动态定位概述
01 引言 RTK(实时动态定位,Real-Time Kinematic)是一种高精度的卫星导航定位技术,通过差分校正方法,将GNSS(全球导航卫星系统)的定位精度从米级提升至厘米级(通常1-3厘米),广泛应用于测绘、无人机、自动驾驶、精准农业等领域。 02 概述 1. RTK的基本原理 RTK的核…...
Conda 环境离线迁移实战:解决生产环境网络限制的高效方案20250409
Conda 环境离线迁移实战:解决生产环境网络限制的高效方案 在生产环境无法联网的前提下,如何高效、安全地部署 Python 虚拟环境,是许多企业在实际运维中必须面对的问题。特别是当前常见的开发环境基于 Miniconda,生产环境使用 Ana…...
dify使用知识库
注意 要用向量模型 导入文件 选择向量模型 要下载好后,才可以导入模型, 这个模型没法在ollama中run 聊天工具添加知识库 效果...
HTTP:一.概述
http是干嘛的? 超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统…...
Appium工作原理及环境的搭建(1)
1、Appium的介绍: 一、什么是Appium Desktop? Appium Desktop是Appium项目的桌面版GUI工具,提供了一个友好的界面,用于启动Appium服务器、查看设备日志、与设备交互、调试自动化脚本等。相比于命令行工具,Appium Des…...
Interactron: Embodied Adaptive Object Detection(训练时进行更新参数) 还没看懂
Interactron: Embodied Adaptive Object Detection 创新点 这些方法通常存在两个主要的共同假设。第一,模型在固定的训练集上进行训练,并在预先录制的测试集上进行评估。第二,模型在训练阶段结束后保持冻结状态,即训练完成后不再…...
【Pandas】pandas DataFrame copy
Pandas2.2 DataFrame Conversion 方法描述DataFrame.astype(dtype[, copy, errors])用于将 DataFrame 中的数据转换为指定的数据类型DataFrame.convert_dtypes([infer_objects, …])用于将 DataFrame 中的数据类型转换为更合适的类型DataFrame.infer_objects([copy])用于尝试…...
Redis基础指令(Windows)
1.cmd命令行启动redis 直接cmd打开整个文件 1.1.启动server 输入指令: redis-server.exe redis.windows.conf 会进入serve端 1.2.启动客户端 !!重新打开一个cmd,方法和上面一样!! 之后输入 redis-…...
MV-DLS600P激光振镜立体相机(MV-DLS600P)重要参数解析
功能特性 采用激光振镜技术,亚毫米级图像采集精度 高能效激光模块配合精准曝光同步,性能更稳定 支持多帧融合,无惧金属工件表面反光干扰 支持RGB、深度图同步对齐输出,便于二次开发 配备窄带滤光片,抗干扰能力更强&…...
C语言【输出字符串中的大写字母】
题目 输出字符串中的大写字母 思路(注意事项) 纯代码 #include<stdio.h> #include<string.h>int main(){char str[20], ans[20];fgets(str, sizeof(str), stdin);str[strcspn(str, "\n")] \0;for (int i 0, j 0; i < strl…...
UniApp基于xe-upload实现文件上传组件
xe-upload地址:文件选择、文件上传组件(图片,视频,文件等) - DCloud 插件市场 致敬开发者!!! 感觉好用的话,给xe-upload的作者一个好评 背景:开发中经常会有…...
deque容器
1.定义 也叫双端数组,可以对头部进行插入和删除。 2.与vector区别 3.内部工作原理 他是把整个地址划分成多块小地址(缓冲区),然后有一个中控区去记录这些地址,然后访问的时候先通过中控区然后再转到相应的缓冲区&am…...
git 总结遇到的问题
git Push 报错 Push failed send-pack: unexpected disconnect while reading sideband packet Total 2269 (delta 418), reused 0 (delta 0), pack-reused 0 the remote end hung up unexpectedly 解决方案:增加 Git 的缓冲区,有时由于数据量大或网络…...
python基础语法11-文件读写
在 Python 中,文件操作是日常编程中的常见任务之一。Python 提供了简单且强大的工具来读取和写入文件。通过使用内置的 open() 函数、read()、readline()、write() 等方法,我们可以轻松实现对文件的操作。此外,Python 的 with 语句可以帮助我…...
Webstorm 使用搜不到node_modules下的JS内容 TS项目按Ctrl无法跳转到函数实现
将node_modules标记为不排除,此时要把内存改大,不然webstorm中途建立索引时,会因为内存不足,导致索引中途停止,造成后续搜索不出来 更改使用内存设置 内存调为4096 若出现搜不出来js内容时,请直接重启下该项…...
转行嵌入式,需要自学多久?
作为一个本硕都学机械,却阴差阳错进入嵌入式行业的老兵,这个问题我能聊一整天。十几年前我还在工厂车间穿着工装和机床打交道,偶然接触到单片机后就一发不可收拾。 转行这条路我走得异常艰辛,踩过的坑比写过的代码还多。去年我终…...
BLE 协议栈事件驱动机制详解
在 BlueNRG-LP 等 BLE 系统中,事件驱动是控制状态转移、数据交互和外设协作的基础。本文将深入讲解 BLE 协议栈中事件的来源、分发流程、处理结构与实际工程实践策略,帮助你构建稳定、可维护的 BLE 系统。 📦 一、BLE 事件的来源分类 BLE 协议栈中的事件严格来自协议栈本身…...
AI开发学习路线(闯关升级版)
以下是一份轻松版AI开发学习路线,用「闯关升级」的方式帮你从零开始变身AI开发者,每个阶段都配有有趣的任务和实用资源,保证不枯燥、可落地!👇 目录 🔰 新手村:打基础(1-2个月&…...
突破,未观测地区罕见极端降雨的估计
文章中文总结(重点为方法细节) 一、研究背景与目的 在无测站或短观测记录地区,传统极值理论(如GEV)难以估计稀有极端降雨事件;本文提出一种新的区域化极值估计方法:区域化 Metastatistical Ex…...
zk源码—4.会话的实现原理一
大纲 1.创建会话 (1)客户端的会话状态 (2)服务端的会话创建 (3)会话ID的初始化实现 (4)设置的会话超时时间没生效的原因 2.分桶策略和会话管理 (1)分桶策略和过期队列 (2)会话激活 (3)会话超时检查 (4)会话清理 1.创建会话 (1)客户端的会话状态 (2)服务端的会话创建…...
快排算法 (分治实现)
本算法采用将整个数组划分成三个部分 <key key >key 在数组全是同一个数字时,也能达到NlogN的时间复杂度 下面的板书中i为遍历数组的下标 left为<key的最右边的下标 right为>key的最左边的下标 例题1:912. 排序数组 - 力扣࿰…...
P9242 [蓝桥杯 2023 省 B] 接龙数列
这道题说要求最少删多少个使剩下的序列是接龙序列,这个问题可以转换为序列中最长的接龙序列是多少,然后用总长度减去最长接龙序列的长度就可以了,在第一个暴力版本的代码中我用了两个for循环求出了所有的接龙序列的长度,但是会超时…...
未来 AI 发展趋势与挑战(AGI、数据安全、监管政策)
从 ChatGPT 的火爆到国内 DeepSeek、通义千问、百川智能等模型的兴起,AI 正以前所未有的速度走入各行各业。而下一阶段,AI 是否会发展出真正的“通用智能”(AGI)?数据隐私、技术伦理又该如何应对?本文将带你全面洞察未来 AI 的技术趋势与落地挑战。 一、AGI 的曙光:通用…...
驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比
🔍 B站相应的视屏教程: 📌 内核:博文视频 - 从静态绑定驱动模型到现代设备模型 主题:深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比 在上一节中,我们从驱动框架的历史演进出…...
MyBatis 动态 SQL 使用详解
🌟 一、什么是动态 SQL? 动态 SQL 是指根据传入参数,动态拼接生成 SQL 语句,不需要写多个 SQL 方法。MyBatis 提供了 <if>、<choose>、<foreach>、<where> 等标签来实现这类操作 ✅ 二、动态 SQL 的优点…...
数据结构实验4.1:链队列的基本操作
文章目录 一,问题描述二,基本要求三,算法分析链队列的存储结构设计基本操作的算法分析 四,示例代码五,实验操作六,运行效果 一,问题描述 编程实现有关链队列的下列基本操作。 (1&am…...
独立部署及使用Ceph RBD块存储
Ceph RBD(RADOS Block Device) 是 Ceph 分布式存储系统中的块存储组件,类似于 AWS EBS、iSCSI 等。它独立于 OpenShift 或 IBM CP4BA,是一个分布式存储系统,提供高性能、可扩展性和容错能力,适用于数据库、…...
C++初阶-C++入门基础
目录 编辑 1.C的简介 1.1C的产生和发展 1.2C的参考文档 1.3C优势和难度 1.4C学习的建议 2.C的第一个程序 2.1打印Hello world 2.2头文件 2.3namespace命名空间 2.4::作用域限定符 2.5namespace的延伸 2.6C的输入输出 3.总结 1.C的简介 …...
部署大模型不再难:DeepSeek + 腾讯云 HAI 实战教程
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
算法训练之位运算
♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…...
初识Linux:常见指令与权限的理解,以及相关衍生知识
目录 前言 关于linux的简介 代码开源 网络功能强大 系统工具链完整 一、Linux下的基本指令 1.ls指令 2.pwd指令 3.cd指令 4.whoami指令 5.touch指令 6.mkdir指令 7.rm指令 8.man指令 9.cp指令 10.mv指令 11.nano指令 12.cat指令 13.tac指令 14.more指令 15.less指令 16.head指令…...
PostgreSQL-数据库的索引 pg_operator_oid_index 损坏
报错信息: 连接测试失败 Error connecting to database: Connection failed: ERROR: index "pg_operator_oid_index" contains unexpected zero page at block 3 Hint: Please REINDEX it. 这个错误表明 PostgreSQL 数据库的索引 pg_operator_oid_index …...
数字图像处理作业4
数字图像处理 作业4 Project 4:Image Restoration The scoring method for this project is as follows: 1.Implement a blurring filter using the equation(5.6-11,数字图像处理(…...
Simulink中Signal Builder在新版中找不到怎么办
在较新的MATLAB版本中,新版Simulink中的Signal Builder用Signal Editor作为替代工具。 signal builder not shown in matlab - MATLAB Answers - MATLAB Central signalBuilderToSignalEditor 1.打开上面第二个链接 2.点击拷贝 3.然后在命令行中粘贴 4.然后就会…...
STM32——RTC实时时钟
RTC简介 RTC(Real Time Clock, RTC)实时时钟,其本质是一个计数器,计数频率常为秒,专门用来记录时间。 其具有能提供时间(秒钟数),能在MCU掉电后运行,低功耗的特性 内部框图 1. RTC预分频器 2. …...
sqli-labs靶场 less4
文章目录 sqli-labs靶场less 4 联合注入 sqli-labs靶场 每道题都从以下模板讲解,并且每个步骤都有图片,清晰明了,便于复盘。 sql注入的基本步骤 注入点注入类型 字符型:判断闭合方式 (‘、"、’、“”…...