doGetBean方法:
该方法位于
-> AbstractApplicationContext.refresh()
-> AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
-> DefaultListableBeanFactory.preInstantiateSingletons()
-> AbstractBeanFactory.getBean(String name)
-> AbstractBeanFactory.doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly)
doGetBean方法大致流程:
doGetBean方法代码:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//通过三种形式获取beanName
//一个是原始的beanName,一个是加了&的,一个是别名
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//尝试从单例缓存集合里获取bean实例
Object sharedInstance = getSingleton(beanName);
//如果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空
//则执行if里面的逻辑
//args之所以要求为空是因为如果有args,则需要做进一步赋值,因此无法直接返回
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//如果Bean还在创建中,则说明是循环引用
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//如果是普通bean,直接返回,如果是FactoryBean,则返回它的getObject
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//若scope为prototype或者单例模式但是缓存中还不存在bean
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//如果scope为prototype并且 显示还在创建中,则基本是循环依赖的情况
//针对prototype的循环依赖,spring误解,直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//从当前容器中找不到指定名称的bean,此时递归去parentFactory查找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//主要针对FactoryBean,将Bean的&重新加上
String nameToLookup = originalBeanName(name);
//如果parent容器依旧是AbstractBeanFactory的实例
//instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
//直接递归调用方法来查找
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
//如果有参数,则委派父类容器根据指定名称和显示的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//委派父级容器根据指定名称查找
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//typeCheckOnly是用来判断调用getBean()是否仅仅是为了类型检查获取bean,而不是为了创建Bean
if (!typeCheckOnly) {
//如果不是仅仅做类型检查则是创建bean
markBeanAsCreated(beanName);
}
try {
//将父类的BeanDefinition与子类的BeanDefinition进行合并覆盖
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//对合并的BeanDefinition做验证,主要看属性是否为abstract的
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean设置了dependsOn的属性
//depends-on用来指定Bean初始化及销毁时的顺序
//<bean id="a" Class="com.imooc.A" depends-on="b" />
//<bean id="b" Class="com.imooc.B" />
if (dependsOn != null) {
for (String dep : dependsOn) {
//校验该依赖是否已经注册给当前bean,注意这里传入的key是当前的bean名称
//这里主要是判断是否有以下这种类型的依赖:
//<bean id="beanA" Class="com.imooc.A" depends-on="beanB" />
//<bean id="beanB" Class="com.imooc.B" depends-on="beanA" />
//如果有,直接抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//缓存依赖调用,注意这里传入的key是被依赖的bean名称
registerDependentBean(dep, beanName);
try {
//递归调用getBean方法,注册Bean之间的依赖(如C需要晚于B初始化,而B需要晚于A初始化)
//初始化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//如果BeanDefinition为单例
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建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.
//显示从单例缓存中删除bean实例
//因为单例模式下为了解决循环依赖,可能它已经存在了,所有将其销毁
destroySingleton(beanName);
throw ex;
}
});
//如果是普通bean,直接返回,如果是FactoryBean,则返回它的getObject
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
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 {
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 && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
代码解析:
1.执行transformedBeanName()方法,该方法将doGetBean的参数name转换成容器中真实的beanName(获取容器中真实beanName)(传递过来的name有三种可能,一个是原始的beanName,一个是加了&的,一个是别名。所以我们要统一将其转换 )
2.getSingleton()方法,该方法将尝试从单例缓存集合里获取bean实例。尝试从一级缓存(singletonObjects)中获取完备的Bean,如果没有则尝试从二级缓存earlySingletonObjects这个存储还没进行属性添加操作的Bean实例缓存中获取,
如果一二级缓存都没有,查看该bean是否允许被循环引用,是则从三级缓存singletonFactories这个ObjectFactory实例的缓存里尝试获取创建此Bean的单例工厂实例,后调用工厂getObject()获取bean实例后存入二级缓存,从三级缓存中移除,返回bean
(1)尝试从一级缓存里面获取完备的Bean(一级缓存中获取完备的Bean)
(2)if(如果没有在一级缓存中获取到Bean & 正在创建Bean的缓存名单中有该BeanName){
尝试给一级缓存对象加锁,接下来就要对缓存对象操作了
尝试从二级缓存earlySingletonObjects这个存储还没进行属性添加操作的Bean实例缓存中获取(二级缓存中获取还未添加属性的Bean)
if(如果还没有获取到并且第二个参数为true,为true则表示bean允许被循环引用){
从三级缓存singletonFactories这个ObjectFactory实例的缓存里尝试获取创建此Bean的单例工厂实例(三级缓存中获取Bean工厂)
if(如果获取到工厂实例){
调用单例工厂的getObject方法返回对象实例,将实例放入二级缓存里,从三级缓存里移除
}
}
}
(3)返回获取的Bean
3.判断从单例缓存集合里获取的bean实例是否存在且是否有args(参数),如果bean存在且没有需要传递的args参数,则进入if,判断其是否有被其他bean引用,如果没被引用,则将bean赋值上(普通bean,直接返回,如果是FactoryBean,则返回它的getObject)