上篇中, 记录了Spring扫描Class, 封装成一个个BeanDefinition的过程, ApplicationContext后续将根据这些Bean定义来创建Bean实例, BeanDefinition和Bean实例保存在的位置如下:
BeanDefinition保存到的实例变量(DefaultListableBeanFactory):
/** List of bean definition names, in registration order */ListbeanDefinitionNames/** Map from bean name to merged RootBeanDefinition */Map mergedBeanDefinitions
Bean实例保存到的成员变量(DefaultListableBeanFactory):
/** 保存单例对象: bean名 --> bean实例 */private final MapsingletonObjects = new ConcurrentHashMap (256);
一个[BeanDefinition]到一个[Bean实例]是通过BeanFactory#getBean方法完成的:
BeanFactory#getBean方法执行过程:
Tags:(BeanFactory具体对应的子类是DefaultListableBeanFactory)
- 从单例缓存singletonObjects查找, 有则直接返回
没有则
- 创建实例
- 执行bean后置处理器,调用Bean初始化方法 依赖注入是后置处理完成的,也是调用BeanFactory#getBean获取依赖对象
- 保存实例到singletonObjects中
参考: [调用beanFactory.getBean获取/创建实例]节点
问题记录
1. 实例化Bean的位置
在上下文刷新时AbstractApplicationContext#refresh
// 执行完全部的BeanFactory后置处理// ConfigurationClassPostProcessor会加载工程下的class到BeanDefinition// 注册Bean后置处理器// 根据BeanDefinition实例化所有单例Bean.finishBeanFactoryInitialization(beanFactory);
2. 对象循环引用问题
getBean方法通过Bean后置处理器AutowiredAnnotationBeanPostProcessor注入依赖, 该后置处理器又将调用getBean获取依赖Bean, 例如有如下代码:
@Servicepublic class ServiceA { @Autowired ServiceB serviceB;}@Servicepublic class ServiceB { @Autowired ServiceA serviceA;}
BeanFactory会将创建中的bean名保存到singletonsCurrentlyInCreation, 创建中的bean实例保存到singletonFactories。
getBean("serviceA")的过程:
- 创建ServiceA实例
- 创建ServiceB实例
- 实例ServiceA注入到ServiceB (实例ServiceA仍在初始化中)
- ServiceB完成创建
- 实例ServiceB注入到ServiceA
- ServiceA完成创建
被依赖的Bean会先完成初始化
参考图片链接:3. 单例Bean创建后注册到哪了?
DefaultSingletonBeanRegistry对象的singletonObjects字段, 这里注册的都是依赖已经注入, 且执行完Bean后置处理器的实例
/** Cache of singleton objects: bean name --> bean instance */private final MapsingletonObjects = new ConcurrentHashMap (256);
4. 对象循环依赖异常
BeanCreationException: Circular depends-on relationship between
@Service@DependsOn("permission")public class Role { @Autowired private Permission permission;}@Service@DependsOn("role")public class Permission { @Autowired private Role role;}
Permission,Role互相依赖, 谁无法被创建, BeanFactory将抛出异常
BeanCreationException:
Circular depends-on relationship between 'role' and 'permission'