贝壳一面:Spring是怎么实现的?谈谈你的理解?

文章内容收录到个人网站,方便阅读hardyfish.top/

Spring 的实现原理可以从它的核心机制和运行流程两方面来说。

1. 核心思想

Spring 的核心是 IoC(控制反转)AOP(面向切面编程) ,它通过容器管理对象的生命周期和依赖关系,并在运行时对类进行动态增强。

  • IoC :对象的创建与依赖由 Spring 容器管理,而不是手动 new
  • AOP:在不改变业务代码的情况下,通过代理技术实现事务、日志、安全等功能的横切关注点。

2. 启动流程(以 Spring 容器为例)

(1)创建容器对象

  • 调用 new ClassPathXmlApplicationContext()AnnotationConfigApplicationContext()
  • 容器初始化时,会读取配置(XML 或注解)并注册 Bean 定义。

(2)BeanDefinition 注册

  • 解析配置文件/注解类,把 Bean 元信息(类名、作用域、依赖等)存到 BeanDefinition 对象中,放入 BeanDefinitionMap

(3)Bean 实例化

  • 调用 反射 创建 Bean 对象(Constructor.newInstance())。
  • 如果有依赖,会先实例化依赖的 Bean(构造器注入 / setter 注入)。

(4)依赖注入

  • 通过反射调用 setXxx() 或直接设置字段值完成注入。
  • 如果使用 @Autowired,Spring 会执行 依赖查找(byType/byName) 并注入。

(5)初始化回调

  • 执行 BeanPostProcessor(如 @PostConstructInitializingBean.afterPropertiesSet())。

(6)AOP 代理

  • 如果 Bean 匹配到切面(@Transactional@Aspect 等),会使用 JDK 动态代理 (接口)或 CGLIB 代理(类继承)创建代理对象,放进容器。

(7)Bean 就绪

  • 容器返回 Bean 的引用给调用方。

3. 核心模块实现细节

(1)IoC 容器实现

  • Spring 的 IoC 容器接口是 BeanFactory,常用实现是 DefaultListableBeanFactory
  • 容器内部维护一个 ConcurrentHashMap<String, Object>(单例池)缓存单例 Bean。

(2)AOP 实现

  • 切面解析 :解析 @Aspect 或 XML 切面配置。
  • 代理创建 :使用 ProxyFactory 结合 JdkDynamicProxy / CglibAopProxy 创建代理类。
  • 方法拦截 :调用链由 MethodInterceptor 组成(事务、日志等)。

(3)事件机制

  • 基于观察者模式实现,ApplicationEventPublisher 用来发布事件,ApplicationListener 订阅事件。

(4)事务管理

  • 基于 AOP 的代理,在方法执行前开启事务(Connection.setAutoCommit(false)),执行后提交或回滚。

4. 特点

  • 高度解耦:对象依赖不直接写死,而是通过容器注入。
  • 灵活扩展 :支持 Bean 后处理器(BeanPostProcessor)、事件监听器等扩展点。
  • 模块化:IoC、AOP、事务、数据访问等模块相互独立又可组合。
相关推荐
颜酱4 分钟前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱5 分钟前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端
码上解惑7 分钟前
从 Dify 工作流说起:常用节点怎么选、怎样组合?
java·人工智能·ai·agent·dify·智能体·spring ai
青山木1 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
嘉伟桑1 小时前
Python调用电价API返回JSON示例:分时电价、现货电价和字段解析
后端
程序员-珍1 小时前
报错下载android sdk失败
android·java
武子康1 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端
糖果店的幽灵1 小时前
langgraph分支之 - 动态分支(Dynamic Branch)
java·前端·javascript·人工智能·langgraph
我叫黑大帅2 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
吃饱了得干活2 小时前
亿级订单表分库分表设计,从0到1全流程
java·数据库·面试