Spring IoC 模块设计文档
注:码友们,我们是从设计的角度一步步学习和分解Spring;所以不要一上来就想看源码,也不需要关心Spring具体加载进去的;我们只封装工具(如IoC),至于调用,暂时不用考虑;(是所谓:抓鲁迅关我周树人什么事)
一、设计理念
此处码友们可以先思考以下,如果仅针对IoC这个点来说,你会如何设计,“动手之前先思考”,所以我想机智的码友会有以下思考:
1、现在将bean的控制权交给框架了,码友不用自己new了,那么肯定要有一个创建bean对象的工具,以及存放创建好的bean的容器;
2、针对创建的对象的工具,从设计角度,首先得支持多种方式吧(比如:XML/注解/Java Config),要不然太局限没人用可还得了;
3、创建好的对象存放的方式,最容易想到的应该是Map,以键值对形式存储;
4、聪明的码友,又会想到既然bean是框架生成和存储的,那么此处会存在一个问题,bean是一下子就能创建好的吗?比如A依赖了B,B依赖了C,那么先创建A的时候,B还没创建,那是不是B就无法完全创建了,B、C同理;那么针对这个问题,肯定要有一个方案去解决,此处假设有个“黑盒”,已经解决了,本篇不论。
5、聪明的码友,思路是不是已经掌握了,万变不离其宗,这个思路握在手里,再细看以下内容。
6、面向对象的核心特性不要忘了:封装、继承、多态
7、23种设计模式、七大软件设计原则也需要作为基础知识,从而去理解和“设计”Spring
1. 控制反转(Inversion of Control, IoC)
-
核心思想:将对象的创建与依赖管理权从应用程序代码转移到框架或容器中。
-
实现目标:
- 解耦组件间的依赖关系,降低代码耦合度。
- 提供统一的配置管理(XML/注解/Java Config),简化对象生命周期管理。
- 支持灵活的扩展性(通过接口、回调、扩展点)。
2. 依赖注入(Dependency Injection, DI)
- 定义:由容器动态注入依赖对象,而非硬编码依赖关系。
- 实现方式:
- 构造器注入(Constructor Injection)。
- Setter 方法注入(Setter Injection)。
- 字段注入(Field Injection,基于注解)。
3. 松耦合与可扩展性
-
松耦合:通过接口抽象与依赖注入,使组件之间无需直接引用具体实现。
-
可扩展性:
- 支持自定义 BeanPostProcessor、BeanFactoryPostProcessor。
- 允许通过 SPI(Service Provider Interface)机制扩展容器功能。
4. 配置元数据
-
支持形式:
- XML 配置(
<bean>
标签)。 - 注解配置(
@Component
、@Autowired
、@Configuration
)。 - Java 配置类(
@Bean
注解)。
- XML 配置(
-
统一抽象:
BeanDefinition
是所有配置的抽象表示,支持多种配置源的解析与注册。
二、核心组件与职责划分
结合设计理念,做组件拆分和定义,这里罗列的是不断迭代后结果,而我们如果从头设计,就只需要重点考虑核心: IoC 容器、Bean 的元数据、配置源
组件名称 | 职责 |
---|---|
BeanFactory | 最基础的 IoC 容器,提供延迟加载(懒加载)Bean 的能力。 |
ApplicationContext | 扩展自 BeanFactory,增加企业级功能(事件发布、国际化、资源加载等)。 |
BeanDefinition | 描述 Bean 的元数据(类名、作用域、依赖关系、初始化/销毁方法等)。 |
BeanDefinitionReader | 解析配置源(XML、注解、Java Config)并生成 BeanDefinition 。 |
BeanFactoryPostProcessor | 在容器加载 BeanDefinition 之前修改配置元数据。 |
BeanPostProcessor | 在 Bean 实例化前后进行拦截处理(如 AOP 代理、属性增强)。 |
三、关键设计模式
你已经是一个成熟的码农了,应该学会套公式了
1. 工厂模式(Factory Pattern)
- 应用场景:
BeanFactory
作为工厂接口,负责创建和管理 Bean 实例。 - 实现类:
DefaultListableBeanFactory
、XmlBeanFactory
。 - 优势:解耦对象创建逻辑与使用逻辑,支持灵活的实例化策略(反射、工厂方法)。
2. 单例模式(Singleton Pattern)
- 应用场景:默认情况下,Spring 容器中的 Bean 为单例作用域(
@Scope("singleton")
)。 - 实现机制:通过
DefaultSingletonBeanRegistry
维护单例池(Map<String, Object>
)。 - 扩展性:支持原型作用域(
@Scope("prototype")
)及自定义作用域。
3. 代理模式(Proxy Pattern)
-
应用场景:AOP 的实现(动态代理)。
-
实现方式:
- JDK 动态代理:基于接口生成代理类(适用于有接口的目标对象)。
- CGLIB 字节码增强:直接修改字节码生成子类代理(适用于无接口的目标对象)。
-
关键类:
ProxyFactory
、JdkDynamicAopProxy
、CglibAopProxy
。
4. 观察者模式(Observer Pattern)
-
应用场景:事件驱动模型(
ApplicationEvent
与ApplicationListener
)。 -
实现机制:
- 事件发布:
ApplicationContext.publishEvent(event)
。 - 事件监听:通过
@EventListener
注解或ApplicationListener
接口注册监听器。
- 事件发布:
5. 模板方法模式(Template Method Pattern)
- 应用场景:
BeanFactory
的初始化流程(refresh()
方法)。 - 实现步骤:
public void refresh() {this.prepareRefresh();registerBeanDefinitions(); // 注册 BeanDefinitionprepareBeanFactory(); // 配置容器postProcessBeanFactory(); // 扩展点instantiateSingletons(); // 实例化单例 Bean
}
四、源码解析
此处就核心逻辑简要说明,后续章节中我们会针对以下章节分别做详细源码解析说明
1. IoC 容器启动流程
-
入口:
ApplicationContext
的refresh()
方法。 -
关键步骤:
- 加载配置:解析 XML/注解/Java Config,生成
BeanDefinition
。 - 注册 BeanDefinition:将
BeanDefinition
存入BeanDefinitionRegistry
。 - 实例化单例 Bean:通过
DefaultListableBeanFactory
的preInstantiateSingletons()
方法。 - 依赖注入:通过
AutowiredAnnotationBeanPostProcessor
注入依赖。
- 加载配置:解析 XML/注解/Java Config,生成
2. Bean 生命周期管理
-
流程图:
[BeanDefinition 加载] → [Bean 实例化] → [属性注入] → [初始化方法] → [使用 Bean] → [销毁方法]
-
关键类:
AbstractAutowireCapableBeanFactory
:负责实例化与属性注入。InitializingBean
:定义afterPropertiesSet()
初始化方法。DisposableBean
:定义destroy()
销毁方法。
3. 依赖注入实现
-
字段注入:
- 通过
AutowiredAnnotationBeanPostProcessor
处理@Autowired
注解。 - 使用
AutowiredFieldElement.inject()
方法完成字段赋值。
- 通过
-
构造器注入:
- 通过
ConstructorResolver.autowireConstructor()
解析构造器参数。
- 通过
4. AOP 与动态代理
-
代理创建:
-
判断目标对象是否为接口:
- 是 → 使用
JdkDynamicAopProxy
。 - 否 → 使用
CglibAopProxy
。
- 是 → 使用
-
-
切面织入:
- 通过
Advisor
定义切面逻辑(Pointcut
+Advice
)。 - 在代理对象的方法调用中插入
invoke()
逻辑(如@Before
、@Around
)。
- 通过
五、高级特性与扩展
1. Bean 作用域
- 单例(Singleton):默认作用域,整个容器共享一个实例。
- 原型(Prototype):每次请求创建新实例。
- Web 作用域:
request
、session
(需 Web 环境支持)。 - 自定义作用域:通过
Scope
接口实现(如ThreadScope
)。
2. 条件化配置
@Conditional
注解:根据条件决定是否注册 Bean。@Profile
注解:按环境激活不同配置(如开发、测试、生产)。
3. 扩展点机制
BeanFactoryPostProcessor
:修改BeanDefinition
(如PropertyPlaceholderConfigurer
)。BeanPostProcessor
:拦截 Bean 实例化过程(如AOPProxy
创建)。
4. 性能优化
- 懒加载(Lazy Initialization):通过
@Lazy
延迟加载 Bean。 - 缓存单例池:
DefaultSingletonBeanRegistry
使用ConcurrentHashMap
提高并发性能。
六、应用场景与示例
1. 基于 XML 的配置
<beans><bean id="userService" class="com.albert.UserService"><property name="userDao" ref="userDao"/></bean><bean id="userDao" class="com.albert.UserDaoImpl"/>
</beans>
2. 基于注解的配置
@Service
public class UserService {@Autowiredprivate UserDao userDao;
}
3. 基于 Java Config 的配置
@Configuration
public class AppConfig {@Beanpublic UserService userService() {return new UserService(userDao());}@Beanpublic UserDao userDao() {return new UserDaoImpl();}
}
七、总结与展望
-
核心价值:
- 通过控制反转与依赖注入,Spring IoC 实现了组件的解耦与复用,显著提升了开发效率与代码可维护性。
-
未来方向:
- 云原生支持:进一步优化容器启动速度与资源占用(如 GraalVM 原生镜像)。
- 无配置化:通过代码生成(如 Lombok)或元编程减少显式配置。
- 服务治理集成:与微服务框架(如 Spring Cloud)深度整合,实现分布式场景下的依赖管理。