【面试】spring中ioc加载过程

文章详细阐述了Spring中Bean从概念态到定义态,再到纯净态和成熟态的加载过程,包括ApplicationContext的实例化、BeanDefinition的创建、Bean的验证、构造方法反射、属性注入(DI)以及AOP代理等关键步骤。

一.加载过程

1.概念态–>定义态
  • 1.实例化一个ApplicationContext的对象
  • 2.调用bean工厂后置处理器(invokeBeanFactoryPostProcessors)完成扫描(如果类上有@Component注解)
  • 3. 循环解析扫描出来的类信息
  • 4.实例化一个BeanDefinition对象来存储解析出来的bean信息
  • 5.把实例化好的beanDefinition对象统一存入BeanDefinitionMap以便之后实例化bean
  • 6.再次调用其它bean工厂后置处理器
2.定义态–>纯净态
  • 1.实例化之前spring要做验证,需要遍历BeanDefinitionMap,依次判断beanDefinition是否Lazy懒加载,是否prototype单多例,是否abstract抽象等等。还有国际化、注册BeanPostProcessor等等。调用finishBeanFactoryInitialization方法来实例化单例的Bean
  • 2.验证完成后,spring在实例化一个bean之前要判断类的构造方法,spring实例化对象是通过构造方法反射实现的,需要知道是哪个构造方法
  • 3. spring调用构造方法反射实例化出一个对象,该对象不是个完整的bean(需要注入属性、或者需要代理等等)
3.纯净态–>成熟态
  • 1.spring处理合并后的beanDefinition
  • 2.判断是否需要完成属性注入(DI),如果需要完成属性注入则开始注入属性
4.初始化
  • 1.判断bean的类型回调Aware接口
  • 2.调用生命周期回调方法
  • 3. 如果需要代理(aop),则完成代理
5.创建完成
  • 1.将bean放入单例池singletonObjects,bean完成后存到spring容器中。
<think>嗯,用户问的是Spring IoC容器的加载过程。我需要先回忆一下Spring框架的相关知识,特别是IoC容器初始化的步骤。首先,IoC容器加载过程主要分为几个阶段,比如资源定位、Bean定义的加载、注册Bean定义,然后是实例化Bean。可能还要提到BeanFactory和ApplicationContext的区别,因为ApplicationContext在初始化时就会加载所有Bean,而BeanFactory是延迟加载的。 接下来,我需要确保每个步骤都解释清楚。资源定位部分,可能涉及到ResourceLoader和Resource接口,用来定位配置文件,比如XML或者注解配置。然后是BeanDefinition的解析,比如XmlBeanDefinitionReader或者AnnotatedBeanDefinitionReader来处理不同的配置方式。解析后的Bean定义会被注册到BeanDefinitionRegistry中,也就是DefaultListableBeanFactory。 然后是Bean的实例化,这里要提到BeanFactoryPostProcessor和BeanPostProcessor,这两个接口在Bean生命周期中很重要。BeanFactoryPostProcessor用来修改Bean定义,比如PropertyPlaceholderConfigurer替换占位符。BeanPostProcessor则是在Bean初始化前后进行处理,比如AOP代理。 还需要注意循环依赖的问题,Spring是如何通过三级缓存解决的。还有初始化阶段,包括属性注入、初始化方法调用、Aware接口的回调等。最后是容器关闭时的销毁过程,比如DisposableBean接口和destroy-method。 用户可能想知道整个流程的详细步骤,而不仅仅是表面。可能需要分步骤解释,确保结构清晰。同时,要避免使用专业术语过多,但又要准确。还要注意用户可能是在准备面试,或者想深入理解Spring原理,所以需要涵盖关键点,比如容器启动流程、Bean生命周期、扩展点等。 需要检查是否有遗漏的步骤,比如环境准备、事件发布机制,比如ApplicationContext的事件发布。ApplicationContext在refresh()方法中完成整个容器的初始化,这个方法是关键。refresh()中的各个步骤,比如prepareRefresh、obtainFreshBeanFactory、prepareBeanFactory、postProcessBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors等等,这些步骤需要详细说明吗? 不过用户的问题比较笼统,可能不需要深入到refresh()的每一个方法,但至少提到关键的阶段。可能还要比较BeanFactory和ApplicationContext的不同,因为ApplicationContext提供了更多企业级功能,比如事件发布、国际化等,而BeanFactory是基础容器。 需要确保回答结构清晰,分点说明,可能用步骤一、步骤二的方式。同时,要符合用户要求的格式,比如行内公式用$...$,但这个问题可能不需要数学公式,所以可能用中文标号即可。还要注意使用中文,语法正确,避免LaTeX错误。 最后总结一下,Spring IoC容器的加载过程大致分为资源定位、加载解析、注册定义、实例化Bean、依赖注入、初始化等步骤,涉及到各种扩展点和生命周期回调。要确保回答覆盖这些点,并且逻辑连贯,帮助用户理解整体流程。</think>Spring IoC容器的加载过程是框架核心机制,可概括为以下步骤: --- ### **1. 资源定位与配置加载** - **入口**:通过`ClassPathXmlApplicationContext`或`AnnotationConfigApplicationContext`启动 - **资源解析**:使用`ResourceLoader`定位配置文件(如`XML`/`Java Config`/注解) - **配置读取**:`BeanDefinitionReader`解析配置为`BeanDefinition`(如`XmlBeanDefinitionReader`解析XML) --- ### **2. BeanDefinition注册** - 解析后的`BeanDefinition`存入`BeanDefinitionRegistry`(核心实现类:`DefaultListableBeanFactory`) - **关键数据结构**:`ConcurrentHashMap`存储Bean定义(键为Bean名称,值为`BeanDefinition`对象) --- ### **3. 容器初始化扩展点** - **BeanFactoryPostProcessor**:修改Bean定义(如`PropertySourcesPlaceholderConfigurer`替换占位符) - **BeanPostProcessor**:干预Bean实例化过程(如AOP代理通过`AbstractAutoProxyCreator`实现) --- ### **4. Bean实例化与依赖注入** - **延迟加载**:`BeanFactory`默认首次调用`getBean()`时实例化 - **立即加载**:`ApplicationContext`在初始化时预实例化所有单例Bean - **依赖注入方式**: - 构造器注入 - Setter注入 - 字段注入(通过`@Autowired`) --- ### **5. Bean生命周期回调** 1. 调用`BeanNameAware`/`BeanFactoryAware`等接口 2. 执行`@PostConstruct`注解方法 3. 调用`InitializingBean.afterPropertiesSet()` 4. 执行自定义`init-method` 5. **销毁阶段**:`@PreDestroy` → `DisposableBean.destroy()` → 自定义`destroy-method` --- ### **6. 容器启动完成** - **事件发布**:通过`ApplicationEventPublisher`发布`ContextRefreshedEvent` - **扩展机制**:可通过`ApplicationListener`监听容器事件 --- ### **关键源码流程(简化版)** ```java // ApplicationContext初始化核心方法 public void refresh() { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); postProcessBeanFactory(beanFactory); // 扩展点:子类定制 invokeBeanFactoryPostProcessors(beanFactory); // 执行BeanFactoryPostProcessor registerBeanPostProcessors(beanFactory); // 注册BeanPostProcessor initMessageSource(); initApplicationEventMulticaster(); onRefresh(); // 子类扩展(如初始化Web容器) registerListeners(); finishBeanFactoryInitialization(beanFactory); // 预实例化单例Bean finishRefresh(); // 发布ContextRefreshedEvent } ``` --- ### **核心设计思想** - **控制反转**:将对象创建与依赖绑定的控制权交给容器 - **扩展性**:通过`BeanPostProcessor`等接口实现高度可扩展性 - **分层架构**:`BeanFactory`提供基础功能,`ApplicationContext`集成企业级特性 理解此流程有助于解决Bean循环依赖、配置加载异常等典型问题,并为自定义扩展(如实现动态代理、自定义注解处理)提供理论基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王佑辉

老板,赏点吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值