springBoot Bean加载流程
当Bean C并不依赖其他Bean时,其创建流程与一般的Spring Bean创建流程基本一致,但在依赖注入等环节会相对简单,以下是其主要的创建流程:
资源定位与加载
- 定位配置资源:Spring启动时,会根据配置文件的路径或名称等信息,通过
ResourceLoader
的getResource()
方法将配置文件定位到具体的资源位置,如类路径下、文件系统等。 - 加载Bean定义:使用相应的
BeanDefinitionReader
实现类,如XmlBeanDefinitionReader
或AnnotationBeanDefinitionReader
的loadBeanDefinitions()
方法来加载配置文件中的Bean C的定义信息。
注册BeanDefinition
- 将上一步加载得到的Bean C的
BeanDefinition
对象注册到BeanDefinitionRegistry
中,通常是DefaultListableBeanFactory
。此时,Bean C的基本信息,如类名、作用域等都已经被解析并存储在BeanDefinition
对象中。
依赖注入前准备
- 在
AbstractBeanFactory
的preInstantiateSingletons()
方法中,会遍历所有已注册的BeanDefinition
对象,对Bean C进行实例化前的准备工作。如果Bean C是非延迟加载的单例Bean,则会调用getBean()
方法进行实例化。
创建Bean实例
- 实例化Bean:
AbstractAutowireCapableBeanFactory
的createBean()
方法是创建Bean C实例的核心方法。首先,它会根据BeanDefinition
获取Bean C的类信息,然后使用反射机制通过instantiateBean()
方法创建一个原始的Bean C实例。
填充属性
- 由于Bean C并不依赖其他Bean,所以在
populateBean()
方法中,不需要进行复杂的依赖注入操作,只需要对一些基本的属性进行设置,如对基本数据类型属性进行赋值等。
执行Aware接口方法
- 在
invokeAwareMethods()
方法中,会检查Bean C实例是否实现了BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
等Aware
接口。如果实现了这些接口,则会调用相应的接口方法,将Bean的名称、类加载器、所属的BeanFactory
等信息传递给Bean C实例。
执行BeanPostProcessor的前置处理方法
- 在
applyBeanPostProcessorsBeforeInitialization()
方法中,会遍历所有已注册的BeanPostProcessor
实现类。对于每个BeanPostProcessor
,会调用其postProcessBeforeInitialization()
方法,对Bean C实例进行前置处理。
执行初始化方法
- 在
invokeInitMethods()
方法中,会根据BeanDefinition
中的配置,调用Bean C实例的初始化方法。如果在Bean C的定义中指定了init-method
属性,则会通过反射调用该方法;如果Bean C实现了InitializingBean
接口,则会调用其afterPropertiesSet()
方法。
执行BeanPostProcessor的后置处理方法
- 与前置处理方法类似,在
applyBeanPostProcessorsAfterInitialization()
方法中,会再次遍历所有已注册的BeanPostProcessor
实现类。对于每个BeanPostProcessor
,会调用其postProcessAfterInitialization()
方法,对经过初始化后的Bean C实例进行后置处理。
Bean注册完成
- 最后,将完全初始化好的Bean C实例添加到单例Bean缓存中,通过
addSingleton()
方法完成Bean C的注册。后续当再次获取该Bean时,直接从缓存中获取即可。