一、获取单例 getSingleton
创建单例bean的代码在getSingleton中实现:
//省略了日志打印和异常捕获的代码
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//单例模式下创建bena需要加锁同步
synchronized (this.singletonObjects) {
//如果bean已经创建,则直接返回就好
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,"...");
}
//这一步是将正在创建的bean记录在缓存中,以便对循环依赖进行检查
beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
//创建单例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
//省略异常捕获
finally {
//移除正在加载的bean记录,与beforeSingletonCreation相对应
afterSingletonCreation(beanName);
}
if (newSingleton) {
//将bean添加到缓存,并且移除加载过程中记录的各种辅助状态
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
因为考虑到多线程获取bean的原因,单例bean的创建是全程加锁的,下面是方法的大致流程:
- 检查缓存中是否已经有bean的实例
- 如果还没有加载,则记录beanName为正在加载状态
- 通过传入的ObjectFactory实例化bean
- 与步骤2对应,移除正在加载的状态
- 添加结果到缓存,并且移除加载bean过程中的各种辅助状态
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
二、ObjectFactory
从上面创建单例的代码可以看到,真正创建bean的功能委托给了ObjectFactory,通过它的getObject方法来创建,那么这个ObjectFactory是在哪里创建的?回顾上一节的doGetBean方法:
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//调用createBean方法
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 创建失败会删除中间状态
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
再看一下其他scope的bean创建:
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
//调用createBean方法
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
//省略catch。。。
}
可以看到,不管是哪种类型的bean,都是通过createBean方法创建的。不一样的是,不同scope的bean在创建前后会有不一样的状态保存工作。
三、createBean方法
1、方法结构
在AbstractBeanFactory中,createBean的方法并未实现,而是将具体创建bean的工作留给了子类,是一个典型的模版方法:
在AbstractAutowireCapableBeanFactory 中实现了该方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 确定并加载bean的class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证以及准备需要覆盖的方法
mbdToUse.prepareMethodOverrides();
try {
// 给BeanPostProcessors 一个机会来返回代理对象来代替真正的实例,在这里实现创建代理对象功能
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//catch...
try {
//创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
//catch
}
上面代码对应步骤:
- 根据设置的class属性或者className来解析、加载class
- 对override属性进行标记和验证(bean XML配置中的lookup-method和replace-method属性)
- 应用初始化前的后处理器,如果处理器中返回了AOP的代理对象,则直接返回该单例对象,不需要继续创建
- 创建bean
2、初始化前的后处理器:InstantiationAwareBeanPostProcessor
createBean方法中调用了resolveBeforeInstantiation 方法做些前置处理,并且如果在这个方法中返回了bean的话(AOP代理对象或者自定义对象),就直接返回这个bean,不再继续后面的创建步骤,方法实现:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//bean还未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//应用实例化前的后处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//如果bean不为空,则应用实例化后的后处理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//标记当前bean是否被解析过
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
a、实例化前的后处理器
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//遍历所有的后处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//应用其中类型为 InstantiationAwareBeanPostProcessor 的后处理器
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
//如果后处理器中创建了代理bean,则直接返回
if (result != null) {
return result;
}
}
}
return null;
}
b、实例化后的后处理器
如果实例化前的后处理器创建了一个代理对象,才会继续应用实例化后的后处理器:
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
应用后处理器的方法与a中类似,只不过调用的是 postProcessBeforeInstantiation ,而后者调用的是 postProcessAfterInstantiation
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
//当其中一个后处理器返回null时,就会中断处理器的调用链,直接返回
if (current == null) {
return result;
}
result = current;
}
return result;
}
四、doCreateBean
终于到了Spring创建bean的地方,下面是代码实现:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 先从factoryBeanInstanceCache缓存中尝试获取
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//如果缓存中不存在,则根据bean对应的策略创建新的实例,如:工厂方法、构造器自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 应用MergedBeanDefinitionPostProcessor 后处理器,合并bean的定义信息
// Autowire等注解信息就是在这一步完成预解析,并且将注解需要的信息放入缓存
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
//catch..
mbd.postProcessed = true;
}
}
// 是否需要提前曝光=单例&允许循环依赖&bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//为了避免循环依赖,在bean初始化完成前,就将创建bean实例的ObjectFactory放入工厂缓存(singletonFactories)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 对bean属性进行填充,注入bean中的属性,会递归初始化依赖的bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法,比如init-method、注入Aware对象、应用后处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//catch
if (earlySingletonExposure) {
//从提前曝光的bean缓存中查询bean,目的是验证是否有循环依赖存在
//如果存在循环依赖,也就是说该bean已经被其他bean递归加载过,放入了提早曝光的bean缓存中
Object earlySingletonReference = getSingleton(beanName, false);
//只有检测到循环依赖的情况下,earlySingletonReference才不会为null
if (earlySingletonReference != null) {
//如果exposedObject没有在 initializeBean 初始化方法中改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//检测依赖
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//因为bean创建后,其依赖的bean一定也是已经创建的
//如果actualDependentBeans不为空,则表示依赖的bean并没有被创建完,即存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException("...");
}
}
}
}
// 根据scope注册bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
//catch。。。
return exposedObject;
}
- 如果是单例则首先清除缓存
- 实例化bean,并使用BeanWarpper包装
- 如果存在工厂方法,则使用工厂方法实例化
- 如果有多个构造函数,则根据传入的参数确定构造函数进行初始化
- 使用默认的构造函数初始化
- 应用MergedBeanDefinitionPostProcessor,Autowired注解就是在这样完成的解析工作
- 依赖处理。如果A和B存在循环依赖,那么Spring在创建B的时候,需要自动注入A时,并不会直接创建再次创建A,而是通过放入缓存中A的ObjectFactory来创建实例,这样就解决了循环依赖的问题
- 属性填充。所有需要的属性都在这一步注入到bean
- 循环依赖检查
- 注册DisposableBean。如果配置了destroy-method,这里需要注册,以便在销毁时调用
- 完成创建并返回