Spring IoC 的工作流程及其各个环节的详细介绍:
1、Spring IoC 容器的初始化
Spring IoC 容器是应用的核心部分,主要通过 BeanFactory 和 ApplicationContext 来实现对象的创建、管理、和依赖注入。
- BeanFactory:BeanFactory 是 Spring 最基础的 IoC 容器接口,负责 Bean 的创建与管理。它使用 延迟加载(Lazy Loading) 方式,只有当 Bean 被请求时才创建对象。
- ApplicationContext:ApplicationContext 是 BeanFactory 的增强版本,提供了更丰富的功能,包括:国际化支持、事件传播、声明式事务、AOP 等。它会在容器启动时一次性加载和创建所有 Bean(预加载模式)。
初始化过程中,Spring 会根据配置加载资源文件或注解(如 XML、JavaConfig、注解扫描等)来构建 IoC 容器。
2、加载配置文件与解析Bean定义
Spring IoC 容器首先需要从配置源(XML、Java配置类、注解)中读取和解析 Bean 的定义。流程如下:
XML 文件加载:如果使用 XML 文件,容器会从配置文件中找到 标签,并解析每个 Bean 的定义,包括其类名、作用域(如单例或原型)、初始化方法、依赖的注入方式等。
注解与Java配置类:如果使用注解或者 Java 配置类,Spring 容器会扫描指定的包路径下的类文件,寻找用 @Component、@Service、@Repository 等注解标注的类,或者从 Java 配置类中标记为 @Bean 的方法来定义 Bean。
所有的 Bean 定义会被容器保存为 BeanDefinition 对象,存储在内存中,等待后续的 Bean 创建与初始化。
3、 BeanDefinition 的注册
一旦 Bean 定义被解析,Spring 会将它们注册到一个 BeanDefinitionRegistry 中。这个注册表包含所有的 BeanDefinition 信息。BeanFactory 或 ApplicationContext 通过访问这个注册表来管理 Bean 的生命周期。
BeanDefinition:它是对 Bean 的抽象描述,包含了类名、构造方法、依赖关系、作用域(singleton、prototype)、初始化和销毁方法等信息。
注册表会记录每个 Bean 的名字、类型、作用域、依赖等信息,供后续使用。
4、 Bean的创建与依赖注入
当容器需要使用某个 Bean 时,它会根据 BeanDefinition 来实例化该 Bean,并完成依赖注入。具体流程包括以下几步(详细可见Bean 的生命周期):
- 实例化(Instantiation):
- 当 BeanFactory 或 ApplicationContext 收到请求时,会根据 BeanDefinition 通过反射机制来创建 Bean 的实例。
- 构造函数注入:如果配置了构造函数注入,容器会使用带参数的构造方法来实例化该 Bean,并在实例化时注入依赖对象。
- Setter 方法注入:如果是通过 Setter 方法注入,容器会先调用无参构造方法创建对象,然后通过 Setter 方法注入依赖。
- 填充属性(Populate Properties):
- 一旦实例化完成,Spring 容器会查看 Bean 需要的属性和依赖(根据 @Autowired 或 XML 配置的依赖),并注入这些依赖。
- Autowired 和 @Qualifier 注解会协同工作来实现依赖的自动装配,确保依赖关系的正确注入。
- Aware 接口回调:
- 如果 Bean 实现了 BeanNameAware、BeanFactoryAware 或 ApplicationContextAware 等特殊接口,Spring 容器会在 Bean 创建完成后自动调用这些接口方法,传递相关的容器信息(例如 BeanFactory 实例或 ApplicationContext 实例)。
- Bean的初始化:
- 如果 Bean 配置了初始化方法(例如通过 init-method 属性或者 @PostConstruct 注解),Spring 会在完成依赖注入后调用初始化方法。
- 另外,Spring 提供了 InitializingBean 接口,其 afterPropertiesSet() 方法也可以用来定制初始化逻辑。
- AOP 代理(可选):
- 如果该 Bean 配置了 AOP(Aspect-Oriented Programming),则在实例化完成后,Spring 会根据 AOP 配置为该 Bean 创建代理对象。
- 代理对象会增强目标对象的行为,比如增加事务处理、日志记录等功能。
5、 Bean的使用
在 Bean 被初始化并准备好后,Spring IoC 容器就可以通过依赖注入将该 Bean 提供给需要它的对象(通常通过构造函数、Setter 方法或字段注入)。
6、 Bean的生命周期管理
Spring IoC 容器还负责管理 Bean 的整个生命周期,包括销毁阶段。
- 销毁(Destruction):当容器关闭时,Spring 会负责调用 Bean 的销毁方法。可以通过 destroy-method 属性配置销毁方法,或实现 DisposableBean 接口的 destroy() 方法。
总结
Spring IoC 的核心流程如下:
- 读取配置文件或注解,加载并解析 Bean 定义。
- 将 Bean 定义存储在 BeanDefinitionRegistry 中。
- 根据需要创建 Bean 实例,并注入所需的依赖。
- 对 Bean 进行初始化处理,必要时创建 AOP 代理对象。
- 管理 Bean 的生命周期,包括销毁处理。