AbstractBeanFactory:单例对象管理能力+可配置;获取bean的总体流程在doGetBean已经成型

/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//将原name转换为规范的beanName;比如去掉FactoryBean的&前缀、将别名转换为规范名
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//尝试从缓存获取单例(所谓的三级缓存,见DefaultSingletonBeanRegistry)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//从缓存中获取到了;可能是完全态的bean,也可能是提前暴露的半成品
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取真正需要获取的对象;例如处理FactoryBean的情况:加&时需要获取bean本身,不加&时需要获取产品bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//从缓存中连半成品bean都没有获取到;则寻找bean定义,根据bean定义创建一个bean
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
//对原型模式的bean,无法解决循环依赖问题,直接抛异常
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//获取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//本BeanFactory没有对应的bean定义,则尝试从父BeanFactory查找bean定义并创建bean
// Not found -> check parent.
//获取name对应的规范名;如果有&前缀则保留
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
//有构造参数则根据对应的构造参数创建bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//本BeanFactory有对应的bean定义,继续往下执行
if (!typeCheckOnly) {
//不需要类型检查,则先标记为已创建?
markBeanAsCreated(beanName);
}
try {
//合并为RootBeanDefinition?
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查;bean定义不能是抽象的
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//初始化此bean之前,必须先初始化它所depends-on的所有bean
//一开始学习的时候将depends-on理解错了,在这里卡了很久。关于depends-on科普:https://blog.youkuaiyun.com/sjyttkl/article/details/72774015
//我理解为depends-on是一种弱依赖关系;而平时常说的“依赖注入“则属于持有其他对象引用的强依赖关系
//不难看出,Spring无法处理循环depends-on的情况
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
//循环depends-on是不合理的,抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册依赖关系
registerDependentBean(dep, beanName);
try {
//底层其实就是调用了doGetBean方法,确保depends-on的bean能被初始化
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//终于开始创建此bean
if (mbd.isSingleton()) {
//单例,则尝试从缓存获取;没有获取到则通过抽象方法createBean(关键方法,所有检索bean的方法最终都通过它来完成实际的创建)创建
//createBean的实现在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
//Spring如何解决循环依赖问题,到这里其实还没有结束,在AbstractAutowireCapableBeanFactory才能有最终答案
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//标记为正在创建
beforePrototypeCreation(beanName);
//原型bean,每次都通过createBean创建新的
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//从正在创建中移除
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//其他Scope的处理;不深究
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
//如若需要则进行类型转换并返回
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}