【Spring】bean的创建生命周期
Bean创建生命周期流程
- 启动ApplicationContext
- 创建BeanFactory
- 初始化BeanFactory
- 执行BeanFactory后置处理器
- Spring扫描
- 生成BeanDefinition
- 合并BeanDefinition
- 加载类
- 实例化前
- 推断构造方法
- 实例化
- BeanDefinition的后置处理
- 实例化后
- 填充属性
- 填充属性后
- 执行Aware
- 初始化前
- 初始化
- 初始化后
启动ApplicationContext
创建BeanFactory
初始化BeanFactory
执行BeanFactory后置处理器
Spring扫描
Spring启动的时候会进行扫描,会先调用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandid
ateComponents(String basePackage) 扫描某个包的路径,并得到BeanDefinition的Set集合。
- 首先,通过ResourcePatternResolver获取指定包路径下的所有.class文件。
- 遍历每个Resource对象
- 利用MetadataReaderFactory解析Resource对象得到MetadataReader
- 利用MetadataReader进行excludeFilters和includeFilters,以及条件注解@Conditional的筛选
- 筛选通过后,基于metadataReader判断排除对应的类是不是接口或者抽象类,
- 如果筛选通过,那么就表示扫描到一个Bean,将ScannedGenericBeanDefinition加入结果集。
MetadataReader表示类的元数据读取器。主要包含一个AnnotationMetadata。功能有
- 获取类的名字
- 获取父类的名字
- 获取所实现的所有接口名字
- 获取所有内部类的名字
- 判断是不是抽象类
- 判断是不是接口
- 判断是不是一个注解
- 获取拥有某个注解的方法集合
- 获取类上添加的所有注解信息
- 获取类上添加的所有注解类型集合
生成BeanDefinition
合并BeanDefinition
加载类
- 优先返回当前线程中的ClassLoader
- 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
- 如果ClassUtils类的加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器。
实例化前
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化前做一些启动动作。这个扩展点叫InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。
推断构造方法
实例化
根据BeanDefinition创建一个对象
BeanDefinition的后置处理
Bean对象实例化出来之后,接下来就应该给对象的属性赋值。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工。
实例化后
在处理完BeanDefinition后,Spring又设计了一个扩展点InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()。
填充属性
填充属性后
执行Aware
完成了属性赋值后,Spring会执行一些回调。包括:
- BeanNameAware:回传beanName给bean对象
- BeanClassLoaderAware:回传classLoader给bean对象
- BeanFactoryAware:回传BeanFactory给对象
初始化前
初始化前,Spring提供了一个扩展点:BeanPostProcessor.postProcessBeforeInitialization()。
初始化
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
执行BeanDefinition中指定的初始化方法
初始化后
Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization()