当前位置: 首页 > 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.lryc.cn/news/603451.html

相关文章:

  • PostgreSQL锁机制详解:从并发控制到死锁检测
  • 分布式时序数据库的特点解析
  • 网络原理 - TCP/IP(一)
  • 字节序详解
  • TCP/IP 传输层详解
  • 【dropdown组件填坑指南】鼠标从触发元素到下拉框中间间隙时,下拉框消失,怎么解决?
  • 分布式链路追踪的实现原理
  • 查询mac 安装所有python 版本
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(5)——Tool Calling(工具调用)
  • 解决mac下git pull、push需要输入密码
  • 学习Scala语言的最佳实践有哪些?
  • 使用 Django REST Framework 构建强大的 API
  • CVE-2022-46169漏洞复现
  • Mysql Connect -- 详解
  • Ollama安装及使用Ollama部署大模型
  • 51c大模型~合集161
  • 【高级深度学习框架】lightning的使用记录
  • 番茄项目2:阶段性目标——用纯python完成这个项目
  • Vue3 状态管理新选择:Pinia 从入门到实战
  • 【JavaScript】手写 Object.prototype.toString()
  • 利用对称算法及非对称算法实现安全启动
  • C++异常捕获:为何推荐按引用(by reference)捕获?
  • 机器学习 线性回归算法及案例实现
  • Generative AI in Game Development
  • 信号上升沿时间与频谱分量的关系
  • 多线程--关于锁的一些知识考点
  • NumPy 2.x 完全指南【三十】整数数组索引
  • 5.1 动⼿实现⼀个 LLaMA2 ⼤模型
  • Effective C++ 条款10:令operator=返回一个reference to *this
  • 【Java面试题】面向对象