Spring--IOC容器的启动流程图解版
目录
一、Spring IOC容器概述
二、IOC容器的启动过程
阶段一:容器初始化
1.1创建 ApplicationContext 实例
1.2refresh() 核心流程
阶段二:Bean 实例化与初始化
一、Spring IOC容器概述
Spring IOC(Inversion of Control,控制反转)容器是Spring框架的核心组件,它负责管理对象的创建、配置和生命周期。IOC容器通过依赖注入(DI)来实现控制反转。
二、IOC容器的启动过程
阶段一:容器初始化
1.1创建 ApplicationContext 实例
这是启动的入口。当我们执行 new ClassPathXmlApplicationContext("beans.xml") 或 new AnnotationConfigApplicationContext(AppConfig.class) 时,容器的骨架就建立起来了。在其构造函数内部,会调用核心的 refresh() 方法。
1.2refresh() 核心流程
- 1.2.1 准备阶段 (prepareRefresh): 设置容器的启动时间、状态标记(激活状态),并验证环境中必需的属性。
- 1.2.2 创建/获取 BeanFactory (obtainFreshBeanFactory): 这是IOC容器的核心。此步骤会创建一个 DefaultListableBeanFactory 实例,并开始加载Bean的“定义信息”(BeanDefinition)。
- XML方式: 解析XML文件,将每个 <bean> 标签转换成一个 BeanDefinition 对象。
- 注解方式: 扫描指定的配置类(@Configuration)和包路径,将带有 @Component、@Service、@Bean 等注解的类转换成 BeanDefinition 对象。
- 注意: 此时只是加载了Bean的“图纸”(元数据),还没有创建任何Bean的实例。
- 1.2.3 准备 BeanFactory (prepareBeanFactory): 对 BeanFactory 进行一系列的设置,比如设置类加载器(ClassLoader)、添加默认的 BeanPostProcessor(Bean后置处理器)等,为后续Bean的创建做好准备。
- 1.2.4 BeanFactory 后置处理 (invokeBeanFactoryPostProcessors): 这是一个非常重要的扩展点。Spring会查找并调用所有实现了 BeanFactoryPostProcessor 接口的Bean。这些处理器可以在所有Bean实例创建之前,读取并修改 BeanDefinition 的元数据。
- 常见应用: PropertySourcesPlaceholderConfigurer 就是一个典型的例子,它会扫描 BeanDefinition 并将 ${...} 占位符替换为配置文件中的实际值。
- 1.2.5 注册 BeanPostProcessor (registerBeanPostProcessors): 查找并注册所有实现了 BeanPostProcessor 接口的Bean。这些处理器将会在后续Bean实例化的各个阶段被调用,用于对Bean实例本身进行增强处理(例如AOP代理)。注意,这里只是注册,并不会立即执行。
- 1.2.6 初始化其他组件: 初始化消息源(用于国际化)、事件广播和注册事件监听器。
- 1.2.7 实例化所有非懒加载单例Bean (finishBeanFactoryInitialization): 容器会遍历所有 BeanDefinition,并主动创建所有作用域为singleton、非lazy-init的Bean。这个过程会触发下面描述的“Bean实例化”阶段。
- 1.2.8 完成刷新 (finishRefresh): 发布 ContextRefreshedEvent 事件,通知所有监听器容器已经刷新完成。这标志着IOC容器已经完全准备就绪。
阶段二:Bean 实例化与初始化
这个阶段由上一步的 finishBeanFactoryInitialization 触发,对每一个单例Bean进行创建。
- 实例化 (Instantiation): Spring通过反射或CGLIB调用Bean的构造函数,创建出一个空白对象。
- 填充属性 (Populate Properties): Spring根据 @Autowired、@Resource 等注解或XML配置,进行依赖注入(DI),将该Bean依赖的其他Bean或值设置到其属性中。
此时可能会出现循环依赖问题,spring使用三级缓存来解决此问题详细请看这篇博客
- 调用Aware接口: 如果Bean实现了 BeanNameAware、BeanFactoryAware、ApplicationContextAware 等接口,Spring会调用相应的方法,将Bean的名称、所在的工厂、所在的上下文等信息注入进来。
- BeanPostProcessor 前置处理: 调用所有已注册的 BeanPostProcessor 的 postProcessBef oreInitialization 方法。这是一个在Bean初始化(init-method)之前进行干预的机会。
- 初始化 (Initialization): 调用Bean自身的初始化方法。如果Bean上定义了 @PostConstruct 注解的方法,或者在XML中配置了 init-method,它们会在此处被执行。
- BeanPostProcessor 后置处理: 调用所有已注册的 BeanPostProcessor 的 postProcessAfterInitialization 方法。这是另一个极其重要的扩展点。
常见应用: Spring AOP的代理对象就是在这里生成的。AbstractAutoProxyCreator 这个后置处理器会检查当前Bean是否需要被代理,如果需要,它会返回一个代理对象来替换原始的Bean实例。所以我们从容器中获取的可能是原始对象,也可能是一个代理对象。
- 放入单例池: 经过以上所有步骤后,一个完整的Bean就创建好了。它会被放入一个Map(通常称为“单例缓存池”或“Singleton Cache”)中,以便后续直接获取。
至此,整个Spring IOC容器的启动流程就完成了。现在,应用程序可以使用 context.getBean() 来获取任何已经初始化好的Bean实例了