Spring IoC 模块设计文档

发布于:2025-06-08 ⋅ 阅读:(21) ⋅ 点赞:(0)

注:码友们,我们是从设计的角度一步步学习和分解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 注解)。
  • 统一抽象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 实例。
  • 实现类DefaultListableBeanFactoryXmlBeanFactory
  • 优势:解耦对象创建逻辑与使用逻辑,支持灵活的实例化策略(反射、工厂方法)。

2. 单例模式(Singleton Pattern)

  • 应用场景:默认情况下,Spring 容器中的 Bean 为单例作用域(@Scope("singleton"))。
  • 实现机制:通过 DefaultSingletonBeanRegistry 维护单例池(Map<String, Object>)。
  • 扩展性:支持原型作用域(@Scope("prototype"))及自定义作用域。

3. 代理模式(Proxy Pattern)

  • 应用场景:AOP 的实现(动态代理)。

  • 实现方式

    • JDK 动态代理:基于接口生成代理类(适用于有接口的目标对象)。
    • CGLIB 字节码增强:直接修改字节码生成子类代理(适用于无接口的目标对象)。
  • 关键类ProxyFactoryJdkDynamicAopProxyCglibAopProxy

4. 观察者模式(Observer Pattern)

  • 应用场景:事件驱动模型(ApplicationEventApplicationListener)。

  • 实现机制

    • 事件发布:ApplicationContext.publishEvent(event)
    • 事件监听:通过 @EventListener 注解或 ApplicationListener 接口注册监听器。

5. 模板方法模式(Template Method Pattern)

  • 应用场景BeanFactory 的初始化流程(refresh() 方法)。
  • 实现步骤
public void refresh() {
	this.prepareRefresh();
    registerBeanDefinitions(); // 注册 BeanDefinition
    prepareBeanFactory();      // 配置容器
    postProcessBeanFactory();  // 扩展点
    instantiateSingletons();   // 实例化单例 Bean
}

四、源码解析

此处就核心逻辑简要说明,后续章节中我们会针对以下章节分别做详细源码解析说明

1. IoC 容器启动流程

  • 入口ApplicationContextrefresh() 方法。

  • 关键步骤

    1. 加载配置:解析 XML/注解/Java Config,生成 BeanDefinition
    2. 注册 BeanDefinition:将 BeanDefinition 存入 BeanDefinitionRegistry
    3. 实例化单例 Bean:通过 DefaultListableBeanFactorypreInstantiateSingletons() 方法。
    4. 依赖注入:通过 AutowiredAnnotationBeanPostProcessor 注入依赖。

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 作用域requestsession(需 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 {
    @Autowired
    private UserDao userDao;
}

3. 基于 Java Config 的配置

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService(userDao());
    }

    @Bean
    public UserDao userDao() {
        return new UserDaoImpl();
    }
}

七、总结与展望

  • 核心价值

    • 通过控制反转与依赖注入,Spring IoC 实现了组件的解耦与复用,显著提升了开发效率与代码可维护性。
  • 未来方向

    • 云原生支持:进一步优化容器启动速度与资源占用(如 GraalVM 原生镜像)。
    • 无配置化:通过代码生成(如 Lombok)或元编程减少显式配置。
    • 服务治理集成:与微服务框架(如 Spring Cloud)深度整合,实现分布式场景下的依赖管理。

在这里插入图片描述