1、前言
上文Spring XML方式获取bean源码初步解析讲述了spring 创建bean的概览后对源码初步的解析。
主要涉及的是:
2.1、获取真正的beanName
2.2、从缓存中获取bean
2.3、获取bean实例
2.4、检测是否是抽象
2.5、处理依赖的bean
2.6、判断是否是单例
2.7、判断是否是原型
2.8、非单例和原型的作用域统一处理
2.9、对获取bean的类型和需要的类型进行校验
其中对于除创建bean之外的步骤都进行了解析,此篇就继续说下创建bean之前的任务。
其中spring对创建bean的步骤进行了分类,分别为单例的情况,原型模式的情况和其他情况三种。创建bean的方法都是相同的。处理原型模式和其他都对创建前后对创建bean做了缓存处理。
这里着重说下单例的情况,其实细节稍微不同外,三种的主要步骤是相同的。
2、查看常见bean之前的细节
这里查看getSingleton创建的细节,查看方法 singletonObjects 单例获取。
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 和 createBean。
2.1、getSingleton 方法解析
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 1.从缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
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 + "'");
}
// 2.放入正在创建的缓存对象
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 3. 从单例工厂Factory中获取,初始化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.
// 4. 从缓存中再次获取
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;
}
}
- 首先从singletonObjects缓存中获取
- 如果没有拿到,那么判断是否需要检测和是否正在创建中,如果是直接报错。
- 从传参ObjectFactory的个体Object方法实例化bean
- 从正在创建的缓存中移除
- 放入缓存,并删除过程中的加载记录
- 返回创建结果
2.2、createBean方法
进入createBean方法,这里是 AbstractBeanFactory 抽象方法createBean 在 AbstractAutowireCapableBeanFactory 中的实现:
@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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 通过beanName class 获取bean对应的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.
// 处理BeanPostProcessors 来代理实例
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);
}
// 创建bean
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);
}
}
- resolveBeanClass 通过beanName,class 获取bean对应的Class对象。并创建新RootBeanDefinition对象。
- mbdToUse.prepareMethodOverrides() 检查重写的方法,这里指的是标签解析的lookup-method 和 replaced-method 对应的方法。
- resolveBeforeInstantiation 实例化的前置处理工作,这里其实就是spring aop 功能实现的原理,通过代理在初始化前后做工作,返回的是可能已经是代理类对应的bean。
- 真正执行实例化 doCreateBean
3、总结
这里总结下这篇文章的内容,在创建bean之前的一些处理。
主要包括封装新的RootBeanDefinition对象,并把解析的class放入,然后处理重写的方法,之后处理BeanPostProcessor 处理的后置工作,最后进行真正创建bean。
下篇说下循环依赖的问题,之前的几篇也说了好几次了,下篇就总结说明下。
希望每天都有所收获,加油!共勉!