浅谈 SpringBean的初始化之 Bean创建准备 ---主线逻辑 ( 三 )
在上一章节从缓存中获取单例 进行了简单的分析,如果缓存中没有已经加载的bean 就得从头开始bean的加载过程了,而如下方法实现了bean的加载过程。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null")
代码及其相关注释:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 全局变量需要同步
synchronized (this.singletonObjects) {
// 先检查对应的bean是否加载过,因为单例模式 就是复用以创建bean
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空才可以 进行singleton 的bean的初始化
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 循环依赖判断
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 初始化bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加入缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
说明:
上述代码并没有做创建bean的操作,而是为创建bean做一些准备。
step1: 检查缓存是否已经加载过
step2:若没有加载,则记录beanName的正在加载状态。
step3: 加载单例前记录加载状态。
其中 beforeSingletonCreation 是记录加载状态,将正在加载的beanName 缓存在singletonsCurrentlyInCreation中。
step4: 通过ObjectFactory 的getObject 实例化bean
step5: 后置处理 afterSingletonCreation
其中afterSingletonCreation 就是当bean 加载结束后,移除缓冲区对该bean的正在加载到状态记录。
step6:将该bean 缓存,同时移除一些相关辅助记录。
接下来看一个核心代码块:
sharedInstance = getSingleton( beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 从单例缓存中移除
destroySingleton(beanName);
throw ex;
}
});
在getSingleton的有一个回调的函数,crateBean也就是getSingleton中的ObjectFactory。真正创建bean的操作其实就是这个createBean方法。
接下来 来简单分析createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 锁定class ,根据class属性 或者根据className 来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 验证 及准备覆盖的方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
步骤说明:
step1 : 根据class 设置的属性或者className 来解析class
step2: 对override 属性进行验证和标记,(解决lookup-method和replaceMethod)
step3 :resolveBeforeInstantiation,解析bean是否在初始化前的短路操作。
step4 :创建bean。
上一篇: Python修改文件的“修改时间”
下一篇: Springboot系列之二:配置数据源