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

SpringBoot 的@Repository 等注解的底层实现原理

1. @Repository注解的类如何存储的

Spring中使用一个IOC容器存储加了 @Component@Repository@Service@Controller 等注解的类,加载IOC容器基本步骤,当 Spring Boot 应用启动时,@SpringBootApplication 中包含的 @ComponentScan 会扫描包及子包下加了这些注解的类。

Spring 会读取每个使用了这些注解类的元数据,创建对应的BeanDefinition并注册到 BeanDefinitionRegistry

2. IOC容器的默认实现

BeanDefinition是一个接口,如果一个类使用派生自@Component的注解,比如@Repository@Service@Controller等,并且通过@ComponentScan注解扫描注册到IOC容器时,默认的接口BeanDefinition实现类是AnnotatedGenericBeanDefinition

BeanDefinitionRegistry也是一个接口,默认的实现是DefaultListableBeanFactory

BeanDefinition中记录的。

3. IOC容器如何管理实例

DefaultListableBeanFactory继承结构图

默认情况下注册到IOC容器中的实例是单例,能保证每次获取到的是同一个实例。

上图是DefaultListableBeanFactory继承结构图,当使用派生自@Component注解一个类时, Spring 内部使用一个三层缓存机制来管理Bean的生命周期,核心是在DefaultSingletonBeanRegistry中维护的。核心源码:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {/*** 一级缓存:存放完全初始化的单例 Bean 实例*/private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 二级缓存、三级缓存用于解决循环依赖,与本文关系不大,省略...
}

4. 从IOC容器中获取实例

IOC容器主要通过getBean()获取托管的Bean实例,该方法由接口BeanFactory声明,由AbstractBeanFactory实现。下面是通过getBean() 方法获取一个 Bean 时的基本执行顺序:

① 是否已经在 singletonObjects 中有现成的 Bean 实例;

② 如果没有并且是懒加载的Bean,就根据对应的 BeanDefinition 实例化一个对象;

③ 实例化之后,放进 singletonObjects 中缓存起来;

④ 之后所有获取请求,都会返回缓存中的同一个对象。

5. IOC容器创建实例时机

**懒加载方式:**上文提到的懒加载时会在getBean时创建实例外的情况,这里不多描述。

**预先实例化单例:**在使用SpringApplication.run()启动SpringBoot应用时,经过多层调用最终会调用SpringApplication.refresh()方法,该方法会根据先前创建的BeanDefinition对象找出scopesingleton且非懒加载的 Bean创建实例对象。

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

相关文章:

  • 智能体安全与可信AI:防护机制与伦理考量
  • SpringBoot之起步依赖
  • 【使用python中列表注意事项】
  • Windows使用Powershell自动安装SqlServer2025服务器与SSMS管理工具
  • 【自存用】mumu模拟器+mitmproxy配置
  • ADSP-21565的SigmaStudio图形化编程详解
  • Linux 完整删除 Systemd 服务的步骤
  • 递归、搜索与回溯算法核心思想解析
  • Agent常用搜索引擎Tavily使用学习
  • linux中简易云盘系统项目实战:基于 TCP协议的 Socket 通信、json数据交换、MD5文件区别与多用户文件管理实现
  • 配置daemon.json使得 Docker 容器能够使用服务器GPU【验证成功】
  • 界面控件Telerik UI for WPF 2025 Q2亮点 - 重要组件全新升级
  • 「源力觉醒 创作者计划」_文心大模型 4.5 多模态实测:开源加速 AI 普惠落地
  • VUE -- 基础知识讲解(一)
  • 从字符串中“薅出”最长子串:LeetCode 340 Swift 解法全解析
  • 分布式链路追踪详解
  • 如何用USRP捕获手机信号波形(中)手机/基站通信
  • Java面试宝典:MySQL8新特性底层原理
  • 设计模式:状态模式 State
  • 【Redis实现基础的分布式锁及Lua脚本说明】
  • 【CAN总线】STM32 的 CAN 总线通信开发笔记(基于 HAL)
  • Spring Boot 自动配置:从 2.x 到 3.x 的进化之路
  • Python 程序设计讲义(28):字符串的用法——格式化字符串
  • 【C++】第十九节—一文万字详解 | AVL树实现
  • Go进阶:流程控制(if/for/switch)与数组切片
  • adb reboot 与 adb shell svc power reboot 的区别
  • 爬虫自动化:一文掌握 PyAutoGUI 的详细使用
  • 【RH134 问答题】第 9 章 访问网络附加存储
  • 智能制造的空间度量:机器视觉标定技术解析
  • 数据结构【红黑树】