上篇《Spring类扫描器记录》中, 记录了Spring扫描Class, 封装成一个个BeanDefinition的过程, ApplicationContext后续将根据这些Bean定义来创建Bean实例, BeanDefinition和Bean实例保存在的位置如下:
BeanDefinition保存到的实例变量(DefaultListableBeanFactory):
/** List of bean definition names, in registration order */
List<String> beanDefinitionNames
/** Map from bean name to merged RootBeanDefinition */
Map<String, RootBeanDefinition> mergedBeanDefinitions
Bean实例保存到的成员变量(DefaultListableBeanFactory):
/** 保存单例对象: bean名 --> bean实例 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(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, 例如有如下代码:
@Service
public class ServiceA {
@Autowired
ServiceB serviceB;
}
@Service
public class ServiceB {
@Autowired
ServiceA serviceA;
}
BeanFactory会将创建中的bean名保存到singletonsCurrentlyInCreation, 创建中的bean实例保存到singletonFactories。
getBean(“serviceA”)的过程:
- 创建ServiceA实例
- 创建ServiceB实例
- 实例ServiceA注入到ServiceB (实例ServiceA仍在初始化中)
- ServiceB完成创建
- 实例ServiceB注入到ServiceA
- ServiceA完成创建
被依赖的Bean会先完成初始化
参考图片链接: Spring循环引用逻辑结构图
3. 单例Bean创建后注册到哪了?
DefaultSingletonBeanRegistry对象的singletonObjects字段, 这里注册的都是依赖已经注入, 且执行完Bean后置处理器的实例
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
4. 对象循环依赖异常
BeanCreationException: Circular depends-on relationship between
循环依赖会导致该异常, 如使用@DependsOn注解配置了依赖:
@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'