该系列文章是本人在学习 Spring 的过程当中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合个人源码注释 Spring 源码分析 GitHub 地址 进行阅读html
Spring 版本:5.1.14.RELEASEjava
开始阅读这一系列文章以前,建议先查看《深刻了解 Spring IoC(面试题)》这一篇文章git
该系列其余文章请查看:《死磕 Spring 之 IoC 篇 - 文章导读》github
前面的一些列文章对面向资源(XML、Properties)、面向注解定义的 Bean 是如何被解析成 BeanDefinition(Bean 的“前身”),并保存至 BeanDefinitionRegistry 注册中内心面,实际也是经过 ConcurrentHashMap 进行保存。面试
Spring 底层 IoC 容器 DefaultListableBeanFactory,实现了 BeanFactory 和 BeanDefinitionRegistry 接口,这个时候它处于“就绪状态”,当咱们显示或者隐式地调用 getBean(...)
方法时,会触发加载 Bean 阶段,获取对应的 Bean。在该方法中,若是是单例模式会先从缓存中获取,已有则直接返回,没有则根据 BeanDefinition 开始初始化这个 Bean。spring
先来看看 BeanFactory 接口的继承关系缓存
简单描述这些接口:安全
org.springframework.beans.factory.BeanFactory
,Spring IoC 容器最基础的接口,提供依赖查找单个 Bean 的功能session
org.springframework.beans.factory.ListableBeanFactory
,继承 BeanFactory 接口,提供依赖查找多个 Bean 的功能app
org.springframework.beans.factory.HierarchicalBeanFactory
,继承 BeanFactory 接口,提供获取父 BeanFactory 的功能,具备层次性
org.springframework.beans.factory.config.ConfigurableBeanFactory
,继承 HierarchicalBeanFactory 接口,提供可操做内部相关组件的功能,具备可配置性
org.springframework.beans.factory.config.AutowireCapableBeanFactory
,继承 BeanFactory 接口,提供可注入的功能,支持依赖注入
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
,继承上面全部接口,综合全部特性,还提供可提早初始化全部单例 Bean 的功能
经过这些接口的名称能够大体了解其用意,接下来咱们来看看它们的实现类的继承关系
简单描述这些实现类:
org.springframework.beans.factory.support.AbstractBeanFactory
抽象类,实现 ConfigurableBeanFactory 接口,基础实现类,Bean 的建立过程交由子类实现org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
抽象类,继承 AbstractBeanFactory,实现 AutowireCapableBeanFactory 接口,完成 Bean 的建立org.springframework.beans.factory.support.DefaultListableBeanFactory
,Spring 底层 IoC 容器,依赖注入的底层实现其余的接口和类和 BeanDefinition 注册中心,别名注册中心,单例 Bean 注册中心相关;右下角的 ApplicationContext 与 Spring 应用上下文有关,它的整个体系这里不作展述,在后面的文章进行分析
org.springframework.beans.factory.support.AbstractBeanFactory
抽象类,实现 ConfigurableBeanFactory 接口,BeanFactory 的基础实现类,提供依赖查找方法,可获取 Bean 对象,接下来咱们来看看依赖查找的实现
getBean(String name)
方法,根据名称获取 Bean,固然还有许多重载方法,以下:
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); }
最终都会调用 doGetBean(...)
这个方法
当咱们显示或者隐式地调用这个方法时,会触发 Bean 的加载;你是否会有疑问,咱们使用 Spring 的过程当中并不会调用这个方法去获取 Bean,那这个方法会被谁调用呢?在 ConfigurableListableBeanFactory 接口中提供提早初始化全部单例 Bean 的功能,在 Spring 应用上下文(ApplicationContext)刷新阶段会提早初始化全部的单例 Bean,这个提早初始化也是调用 getBean 这个方法,这部份内容在后续分析 Spring 应用上下文的生命周期会讲到
doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly)
方法,获取一个 Bean,方法以下:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // <1> 获取 `beanName` // 由于入参 `name` 多是别名,也多是 FactoryBean 类型 Bean 的名称(`&` 开头,须要去除) // 因此须要获取真实的 beanName final String beanName = transformedBeanName(name); Object bean; // <2> 先从缓存(仅缓存单例 Bean )中获取 Bean 对象,这里缓存指的是 `3` 个 Map // 缓存中也多是正在初始化的 Bean,能够避免**循环依赖注入**引发的问题 // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); // <3> 若从缓存中获取到对应的 Bean,且 `args` 参数为空 if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { 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 + "'"); } } // <3.1> 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 缓存中没有对应的 Bean,则开启 Bean 的加载 else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // <4> 若是**非单例模式**下的 Bean 正在建立,这里又开始建立,代表存在循环依赖,则直接抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); // <5> 若是从当前容器中没有找到对应的 BeanDefinition,则从父容器中加载(若是存在父容器) if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. // <5.1> 获取 `beanName`,由于多是别名,则进行处理 // 和第 `1` 步不一样,不须要对 `&` 进行处理,由于进入父容器从新依赖查找 String nameToLookup = originalBeanName(name); // <5.2> 若为 AbstractBeanFactory 类型,委托父容器的 doGetBean 方法进行处理 // 不然,就是非 Spring IoC 容器,根据参数调用相应的 `getBean(...)`方法 if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } // <6> 若是不是仅仅作类型检查,则表示须要建立 Bean,将 `beanName` 标记为已建立过 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { // <7> 从容器中获取 `beanName` 对应的的 RootBeanDefinition(合并后) final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 检查是否为抽象类 checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // <8> 获取当前正在建立的 Bean 所依赖对象集合(`depends-on` 配置的依赖) String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // <8.1> 检测是否存在循环依赖,存在则抛出异常 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // <8.2> 将 `beanName` 与 `dep` 之间依赖的关系进行缓存 registerDependentBean(dep, beanName); try { // <8.3> 先建立好依赖的 Bean(从新调用 `getBean(...)` 方法) getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. // <9> 开始建立 Bean,不一样模式建立方式不一样 if (mbd.isSingleton()) { // <9.1> 单例模式 /* * <9.1.1> 建立 Bean,成功建立则进行缓存,并移除缓存的早期对象 * 建立过程实际调用的下面这个 `createBean(...)` 方法 */ sharedInstance = getSingleton(beanName, // ObjectFactory 实现类 () -> { try { // **【核心】** 建立 Bean 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; } }); // <9.1.2> 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // <9.2> 原型模式 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { // <9.2.1> 将 `beanName` 标记为原型模式正在建立 beforePrototypeCreation(beanName); // <9.2.2> **【核心】** 建立 Bean prototypeInstance = createBean(beanName, mbd, args); } finally { // <9.2.3> 将 `beanName` 标记为不在建立中,照应第 `9.2.1` 步 afterPrototypeCreation(beanName); } // <9.2.4> 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } // <9.3> 其余模式 else { // <9.3.1> 获取该模式的 Scope 对象 `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 { // <9.3.1> 从 `scope` 中获取 `beanName` 对应的对象(看你的具体实现),不存在则执行**原型模式**的四个步骤进行建立 Object scopedInstance = scope.get(beanName, () -> { // 将 `beanName` 标记为原型模式正在建立 beforePrototypeCreation(beanName); try { // **【核心】** 建立 Bean return createBean(beanName, mbd, args); } finally { // 将 `beanName` 标记为不在建立中,照应上一步 afterPrototypeCreation(beanName); } }); // 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 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. // <10> 若是入参 `requiredType` 不为空,而且 Bean 不是该类型,则须要进行类型转换 if (requiredType != null && !requiredType.isInstance(bean)) { try { // <10.1> 经过类型转换机制,将 Bean 转换成 `requiredType` 类型 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); // <10.2> 转换后的 Bean 为空则抛出异常 if (convertedBean == null) { // 转换失败,抛出 BeanNotOfRequiredTypeException 异常 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } // <10.3> 返回类型转换后的 Bean 对象 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()); } } // <11> 返回获取到的 Bean return (T) bean; }
这个方法的处理过程有点长,以下:
获取 beanName
,由于入参 name
多是别名,也多是 FactoryBean 类型 Bean 的名称(&
开头,须要去除),因此须要获取真实的 beanName
先从缓存(仅缓存单例 Bean )中获取 Bean 对象,这里缓存指的是 3
个 Map;缓存中也多是正在初始化的 Bean,能够避免循环依赖注入引发的问题
若从缓存中获取到对应的 Bean,且 args
参数为空
【同】调用 getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd)
方法
获取 Bean 的目标对象,scopedInstance
非 FactoryBean 类型直接返回,不然,调用 FactoryBean#getObject() 获取目标对象
缓存中没有对应的 Bean,则开启 Bean 的加载
若是非单例模式下的 Bean 正在建立,这里又开始建立,代表存在循环依赖,则直接抛出异常
若是从当前容器中没有找到对应的 BeanDefinition,则从父容器中加载(若是存在父容器)
beanName
,由于多是别名,则进行处理,和第 1
步不一样,不须要对 &
进行处理,由于进入父容器从新依赖查找getBean(...)
方法若是不是仅仅作类型检查,则表示须要建立 Bean,将 beanName
标记为已建立过,在后面的循环依赖检查中会使用到
从容器中获取 beanName
对应的的 RootBeanDefinition(合并后),调用 getMergedLocalBeanDefinition(String beanName)
方法
获取当前正在建立的 Bean 所依赖对象集合(depends-on
配置的依赖)
beanName
与 dep
之间依赖的关系进行缓存getBean(...)
方法)开始建立 Bean,不一样模式建立方式不一样
单例模式
建立 Bean,成功建立则进行缓存,并移除缓存的早期对象,调用 getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法
【核心】入参的 ObjectFactory 实现类就是调用的 AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
方法
【同】 和上面的 3.1
相同操做
原型模式
beanName
标记为非单例模式正在建立AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
方法beanName
标记为不在建立中,照应第 9.2.1
步3.1
相同操做其余模式
scope
,不存在则抛出异常scope
中获取 beanName
对应的对象(看你的具体实现),不存在则执行原型模式的四个步骤进行建立若是入参 requiredType
不为空,而且 Bean 不是该类型,则须要进行类型转换
requiredType
类型返回获取到的 Bean
归纳:
能够看到这个方法加载 Bean 的过程当中,会先从缓存中获取单例模式的 Bean;
不论是从缓存中获取的仍是新建立的,都会进行处理,若是是 FactoryBean 类型则调用其 getObject() 获取目标对象;
BeanFactory 可能有父容器,若是当前容器找不到 BeanDefinition 则会尝试让父容器建立;
建立 Bean 的任务交由 AbstractAutowireCapableBeanFactory 去完成;
若是获取到的 Bean 不是咱们想要类型,会经过类型转换机制转换成目标类型
接下来依次分析上述过程的相关步骤(doGetBean(...)
)
对应代码段:
// AbstractBeanFactory.java final String beanName = transformedBeanName(name);
由于入参 name
多是别名,也多是 FactoryBean 类型 Bean 的名称(&
开头,须要去除),因此须要进行一番转换,以下:
// AbstractBeanFactory.java protected String transformedBeanName(String name) { return canonicalName(BeanFactoryUtils.transformedBeanName(name)); } // BeanFactoryUtils.java public static String transformedBeanName(String name) { Assert.notNull(name, "'name' must not be null"); if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { return name; } // 获取 name 对应的 beanName, // 不为 null 则返回 `transformedBeanNameCache` 缓存中对应的 beanName, // 为 null 则对 name 进行处理,将前缀 '&' 去除,直至没有 '&',而后放入 `transformedBeanNameCache` 缓存中,并返回处理后的 beanName return transformedBeanNameCache.computeIfAbsent(name, beanName -> { do { beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); } while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); return beanName; }); } // SimpleAliasRegistry.java public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; // 循环,从 aliasMap 中,获取到最终的 beanName do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }
过程并不复杂,先将前缀 &
去除(若是存在),若是是别名则获取对应的 beanName
定义了一个 FactoryBean 类型的 Bean,名称为
user
,经过user
获取 Bean,获取到的是 FactoryBean#getObject() 返回的对象(只会被调用一次)经过
&user
获取 Bean,获取到的是 FactoryBean 自己这个对象
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 Object sharedInstance = getSingleton(beanName);
单例模式的 Bean 被建立后会缓存,为了不循环依赖注入,在建立过程会临时缓存正在建立的 Bean(早期 Bean),在后续文章会讲到,从缓存中获取对象过程以下:
// DefaultSingletonBeanRegistry.java public Object getSingleton(String beanName) { return getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { // <1> **【一级 Map】**从单例缓存 `singletonObjects` 中获取 beanName 对应的 Bean Object singletonObject = this.singletonObjects.get(beanName); // <2> 若是**一级 Map**中不存在,且当前 beanName 正在建立 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // <2.1> 对 `singletonObjects` 加锁 synchronized (this.singletonObjects) { // <2.2> **【二级 Map】**从 `earlySingletonObjects` 集合中获取,里面会保存从 **三级 Map** 获取到的正在初始化的 Bean singletonObject = this.earlySingletonObjects.get(beanName); // <2.3> 若是**二级 Map** 中不存在,且容许提早建立 if (singletonObject == null && allowEarlyReference) { // <2.3.1> **【三级 Map】**从 `singletonFactories` 中获取对应的 ObjectFactory 实现类 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); // 若是从**三级 Map** 中存在对应的对象,则进行下面的处理 if (singletonFactory != null) { // <2.3.2> 调用 ObjectFactory#getOject() 方法,获取目标 Bean 对象(早期半成品) singletonObject = singletonFactory.getObject(); // <2.3.3> 将目标对象放入**二级 Map** this.earlySingletonObjects.put(beanName, singletonObject); // <2.3.4> 从**三级 Map**移除 `beanName` this.singletonFactories.remove(beanName); } } } } // <3> 返回从缓存中获取的对象 return singletonObject; }
过程以下:
singletonObjects
中获取 beanName 对应的 BeansingletonObjects
加锁earlySingletonObjects
集合中获取,里面会保存从 三级 Map 获取到的正在初始化的 BeansingletonFactories
中获取对应的 ObjectFactory 实现类,若是从三级 Map 中存在对应的对象,则进行下面的处理这个过程对应《深刻了解 Spring IoC(面试题)》中的BeanFactory 是如何处理循环依赖问题
通常状况下,Spring 经过反射机制利用 Bean 的 beanClass 属性指定实现类来实例化 Bean。某些状况下,Bean 的实例化过程比较复杂,若是按照传统的方式,则须要提供大量的配置信息,配置方式的灵活性有限,这时采用编码的方式可能会获得一个简单的方案。Spring 为此提供了一个 FactoryBean 的工厂 Bean 接口,用户能够经过实现该接口定制实例化 Bean 的逻辑。
FactoryBean 接口对于 Spring 框架自己也很是重要,其内部就提供了大量 FactoryBean 的实现。它们隐藏了实例化过程当中一些复杂细节,给上层应用带来了便利。
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
不论是从缓存中获取的仍是新建立的,都会调用这个方法进行处理,若是是 FactoryBean 类型则调用其 getObject() 获取目标对象
// AbstractBeanFactory.java protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. // <1> 若 `name` 以 `&` 开头,说明想要获取 FactoryBean,则校验其**正确性** if (BeanFactoryUtils.isFactoryDereference(name)) { // <1.1> 若是是 NullBean 空对象,则直接返回 if (beanInstance instanceof NullBean) { return beanInstance; } // <1.2> 若是不是 FactoryBean 类型,则抛出异常 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the caller actually wants a reference to the factory. // 到这里咱们就有了一个 Bean,多是一个正常的 Bean,也多是一个 FactoryBean // 若是是 FactoryBean,则须要经过其 getObject() 方法获取目标对象 // <2> 若是 `beanInstance` 不是 FactoryBean 类型,不须要再处理则直接返回 // 或者(表示是 FactoryBean 类型) `name` 以 `&` 开头,表示你想要获取实际 FactoryBean 对象,则直接返回 // 还不符合条件的话,表示是 FactoryBean,须要获取 getObject() 返回目标对象 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; // <3> 若是入参没有传 BeanDefinition,则从 `factoryBeanObjectCache` 缓存中获取对应的 Bean 对象 // 入参传了 BeanDefinition 表示这个 Bean 是刚建立的,不走缓存,须要调用其 getObject() 方法获取目标对象 // `factoryBeanObjectCache`:FactoryBean#getObject() 调用一次后返回的目标对象缓存在这里 if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } // <4> 若第 `3` 步获取的对象为空,则须要调用 FactoryBean#getObject() 得到对象 if (object == null) { // Return bean instance from factory. // <4.1> 将 `beanInstance` 转换成 FactoryBean 类型 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. // <4.2> 若是入参没有传 BeanDefinition 而且当前容器存在对应的 BeanDefinition if (mbd == null && containsBeanDefinition(beanName)) { // 获取对应的 RootBeanDefinition(合并后) mbd = getMergedLocalBeanDefinition(beanName); } // 是不是用户定义的(不是 Spring 建立解析出来的) boolean synthetic = (mbd != null && mbd.isSynthetic()); // <4.3> **【核心】**经过 FactoryBean 得到目标对象,单例模式会缓存在 `factoryBeanObjectCache` 中 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
过程以下:
若 name
以 &
开头,说明想要获取 FactoryBean,则校验其正确性
若是 beanInstance
不是 FactoryBean 类型,不须要再处理则直接返回;或者(表示是 FactoryBean 类型) name
以 &
开头,表示你想要获取实际 FactoryBean 对象,则直接返回;还不符合条件的话,表示是 FactoryBean,须要获取 getObject() 返回目标对象,往下处理
若是入参没有传 BeanDefinition,则从 factoryBeanObjectCache
缓存中获取对应的 Bean 对象,以下:
// FactoryBeanRegistrySupport.java protected Object getCachedObjectForFactoryBean(String beanName) { return this.factoryBeanObjectCache.get(beanName); }
factoryBeanObjectCache
:FactoryBean#getObject() 调用一次后返回的目标对象缓存在这里
入参传了 BeanDefinition 表示这个 Bean 是刚建立的,不走缓存,须要调用其 getObject() 方法获取目标对象
若第 3
步获取的对象为空,则须要调用 FactoryBean#getObject() 得到对象
beanInstance
转换成 FactoryBean 类型factoryBeanObjectCache
中,调用 getObjectFromFactoryBean(FactoryBean<?>, String, boolean)
方法getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)
方法,获取 FactoryBean 的目标对象,方法以下:
// FactoryBeanRegistrySupport.java protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // <1> `factory` 为单例模式,且单例 Bean 缓存中存在 `beanName` 对应的 FactoryBean 对象 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // <1.1> 获取单例锁,保证安全 // <1.2> 从 `factoryBeanObjectCache` 缓存中获取 FactoryBean#getObject() 建立的目标对象 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // <1.3> 则根据 `factory` 获取目标对象,调用 FactoryBean#getObject() 方法 object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) // <1.4> 这里再进行一次校验,看是否在缓存中存在 FactoryBean 建立的目标对象,若是有则优先从缓存中获取 // 保证 FactoryBean#getObject() 只能被调用一次 // 没有的话,则对刚获取到的目标对象进行接下来的处理 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { // <1.5> 是否须要后续处理,这个 FactoryBean 的前身 BeanDefinition 是否由 Spring 解析出来的,一般状况下都是 if (shouldPostProcess) { // <1.5.1> 若该 FactoryBean 处于建立中,则直接返回这个目标对象,不进行接下来的处理过程 if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } // <1.5.2> 前置处理,将 `beanName` 标志为正在建立 beforeSingletonCreation(beanName); try { // <1.5.3> 对经过 FactoryBean 获取的目标对象进行后置处理 // 遍历全部的 BeanPostProcessor 的 postProcessAfterInitialization 方法(初始化的处理) object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { // <1.5.4> 后置处理,将 `beanName` 标志为不在建立中 afterSingletonCreation(beanName); } } // <1.6> 若是缓存中存在 `beanName` 对应的 FactoryBean 对象 // 上面不是判断了吗?也可能在上面的处理过程会有所变化,因此这里在作一层判断 // 目的:缓存 FactoryBean 建立的目标对象,则须要保证 FactoryBean 自己这个对象存在缓存中 if (containsSingleton(beanName)) { // <1.6.1> 将这个 FactoryBean 建立的目标对象保存至 `factoryBeanObjectCache` this.factoryBeanObjectCache.put(beanName, object); } } } // <1.7> 返回 FactoryBean 建立的目标对象 return object; } } // <2> `factory` 非单例模式,或单例 Bean 缓存中不存在 `beanName` 对应的 FactoryBean 对象 else { // <2.1> 则根据 `factory` 获取目标对象,调用 FactoryBean#getObject() 方法 Object object = doGetObjectFromFactoryBean(factory, beanName); // <2.2> 是否须要后续处理,这个 FactoryBean 的前身 BeanDefinition 是否由 Spring 解析出来的,一般状况下都是 if (shouldPostProcess) { try { // <2.2.1> 对经过 FactoryBean 获取的目标对象进行后置处理 // 遍历全部的 BeanPostProcessor 的 postProcessAfterInitialization 方法(初始化的处理) object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } // <2.3> 返回 FactoryBean 建立的目标对象,非单例模式不会进行缓存 return object; } }
过程以下:
factory
为单例模式,且单例 Bean 缓存中存在 beanName
对应的 FactoryBean 对象
获取单例锁,保证安全
从 factoryBeanObjectCache
缓存中获取 FactoryBean#getObject() 建立的目标对象
则根据 factory
获取目标对象,调用 FactoryBean#getObject() 方法(反射机制)
这里再进行一次校验(第 1.2
已经判断过),看是否在缓存中存在 FactoryBean 建立的目标对象,若是有则优先从缓存中获取,保证 FactoryBean#getObject() 只能被调用一次;没有的话,则对刚获取到的目标对象进行接下来的处理
是否须要后续处理,这个 FactoryBean 的 BeanDefinition 是否由 Spring 解析出来的,一般状况下都是
若该 FactoryBean 处于建立中,则直接返回这个目标对象,不进行接下来的处理过程
前置处理,将 beanName
标志为正在建立
对经过 FactoryBean 获取的目标对象进行后置处理,遍历全部的 BeanPostProcessor 的 postProcessAfterInitialization 方法(初始化的处理)
后置处理,将 beanName
标志为不在建立中
若是缓存中存在 beanName
对应的 FactoryBean 对象,上面不是判断了吗(第 1
步判断过)?
也可能在上面的处理过程会有所变化,因此这里在作一层判断,目的:缓存 FactoryBean 建立的目标对象,则须要保证 FactoryBean 自己这个对象存在缓存中
factoryBeanObjectCache
返回 FactoryBean 建立的目标对象
factory
非单例模式,或单例 Bean 缓存中不存在 beanName
对应的 FactoryBean 对象
factory
获取目标对象,调用 FactoryBean#getObject() 方法(反射机制)归纳:调用 FactoryBean#getObject() 获取目标对象,单例模式会缓存起来;过程当中 Sping 考虑到各类状况,例如保证单例模式下 FactoryBean#getObject() 只调用一次,是否须要进行后置处理。
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } protected boolean isPrototypeCurrentlyInCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); return (curVal != null && (curVal.equals(beanName) // 相等 || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName)))); // 包含 }
prototypesCurrentlyInCreation
中保存非单例模式下正在建立的 Bean 的名称,这里又从新建立,表示出现循环依赖,则直接抛出异常
Spring 对于非单例模式的 Bean 没法进行相关缓存,也就没法处理循环依赖的状况,选择了直接抛出异常
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 BeanFactory parentBeanFactory = getParentBeanFactory(); // <5> 若是从当前容器中没有找到对应的 BeanDefinition,则从父容器中加载(若是存在父容器) if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. // <5.1> 获取 `beanName`,由于多是别名,则进行处理 // 和第 `1` 步不一样,不须要对 `&` 进行处理,由于进入父容器从新依赖查找 String nameToLookup = originalBeanName(name); // <5.2> 若为 AbstractBeanFactory 类型,委托父容器的 doGetBean 方法进行处理 // 不然,就是非 Spring IoC 容器,根据参数调用相应的 `getBean(...)`方法 if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } }
若是当前 BeanFactory 没有对应的 BeanDefinition,也就没法建立 Bean,可是若是存在父 BeanFactory,则将接下来的操做交由父 BeanFactory,找不到会层层找上去,若是全部 BeanFactory 都找不到对应的 BeanDefinition 最终会抛出异常。
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 // <6> 若是不是仅仅作类型检查,则表示须要建立 Bean,将 `beanName` 标记为已建立过 if (!typeCheckOnly) { markBeanAsCreated(beanName); }
若是不是仅仅作类型检查,则调用 markBeanAsCreated(String beanName)
方法,以下:
// AbstractBeanFactory.java protected void markBeanAsCreated(String beanName) { // 没有建立 if (!this.alreadyCreated.contains(beanName)) { // 加上全局锁 synchronized (this.mergedBeanDefinitions) { // 再次检查一次:DCL 双检查模式 if (!this.alreadyCreated.contains(beanName)) { // Let the bean definition get re-merged now that we're actually creating // the bean... just in case some of its metadata changed in the meantime. // 从 mergedBeanDefinitions 中删除 beanName,并在下次访问时从新建立它 clearMergedBeanDefinition(beanName); // 添加到已建立 bean 集合中 this.alreadyCreated.add(beanName); } } } }
将这个 beanName
保存在 alreadyCreated
集合中(SetFromMap),在后面的循环依赖检查中会使用到
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 // <7> 从容器中获取 `beanName` 对应的的 RootBeanDefinition(合并后) final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 检查是否为抽象类 checkMergedBeanDefinition(mbd, beanName, args);
由于咱们定义的 Bean 大多数都被 Spring 解析成 GenericBeanDefinition 类型,具备父子关系,则须要获取最终的 BeanDefinition;若是存在父子关系,则会进行一系列的合并,转换成 RootBeanDefinition 对象,调用 getMergedLocalBeanDefinition(String beanName)
方法,以下:
// AbstractBeanFactory.java protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. // 从 `mergedBeanDefinitions` 缓存中获取合并后的 RootBeanDefinition,存在则直接返回 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } // 获取 BeanDefinition 并转换成,若是存在父子关系则进行合并 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null); } protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException { // 加锁 synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance. if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } if (mbd == null) { // 若是没有父类则直接转换成 RootBeanDefinition 对象 if (bd.getParentName() == null) { // Use copy of given root bean definition. if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } // 有父类则进行合并 else { // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try { // 获取父类的对应的 BeanDefinition 对象 String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); } else { BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } // Deep copy with overridden values. mbd = new RootBeanDefinition(pbd); // 父子合并 mbd.overrideFrom(bd); } // Set default singleton scope, if not configured before. if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } // A bean contained in a non-singleton bean cannot be a singleton itself. // Let's correct this on the fly here, since this might be the result of // parent-child merging for the outer bean, in which case the original inner bean // definition will not have inherited the merged outer bean's singleton status. if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } // Cache the merged bean definition for the time being // (it might still get re-merged later on in order to pick up metadata changes) if (containingBd == null && isCacheBeanMetadata()) { // 放入缓存中 this.mergedBeanDefinitions.put(beanName, mbd); } } return mbd; } }
过程大体以下:
mergedBeanDefinitions
缓存中获取合并后的 RootBeanDefinition,存在则直接返回,不存在则进行后面的操做后续还会对合并后的 RootBeanDefinition 对象进行检查,若是是抽象的,则抛出异常
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 // Guarantee initialization of beans that the current bean depends on. // <8> 获取当前正在建立的 Bean 所依赖对象集合(`depends-on` 配置的依赖) String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // <8.1> 检测是否存在循环依赖,存在则抛出异常 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // <8.2> 将 `beanName` 与 `dep` 之间依赖的关系进行缓存 registerDependentBean(dep, beanName); try { // <8.3> 先建立好依赖的 Bean(从新调用 `getBean(...)` 方法) getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } }
每一个 Bean 不必定是单独工做的,能够经过 depends-on
配置依赖的 Bean,其余 Bean 也能够依赖它
对于依赖的 Bean,会优先加载,因此在 Spring 的加载顺序中,在初始化某个 Bean 的时候,首先会初始化这个 Bean 的依赖
在初始化依赖的 Bean 以前,会调用 isDependent(String beanName, String dependentBeanName)
方法,判断是否出现循环依赖,方法以下:
DefaultSingletonBeanRegistry.java protected boolean isDependent(String beanName, String dependentBeanName) { synchronized (this.dependentBeanMap) { return isDependent(beanName, dependentBeanName, null); } } private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) { // <1> `alreadySeen` 中已经检测过该 `beanName` 则直接返回 `false` if (alreadySeen != null && alreadySeen.contains(beanName)) { return false; } // <2> 获取最终的 `beanName`,由于多是别名,须要进行相关处理 String canonicalName = canonicalName(beanName); // <3> 从 `dependentBeanMap` 中获取依赖 `beanName` 的 Bean 集合 Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); // <4> 没有 Bean 依赖该 `beanName`,也就不存在循环依赖,返回 `false` if (dependentBeans == null) { return false; } // <5> 依赖 `beanName` 的 Bean 们包含 `dependentBeanName`,表示出现循环依赖,返回 `true` if (dependentBeans.contains(dependentBeanName)) { // `beanName` 与 `dependentBeanName` 相互依赖 return true; } // <6> 对依赖该 `beanName` 的 Bean 们进行检查,看它们是否与 `dependentBeanName` 存在依赖,递归处理 for (String transitiveDependency : dependentBeans) { if (alreadySeen == null) { alreadySeen = new HashSet<>(); } alreadySeen.add(beanName); if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { return true; } } return false; }
过程大体以下:
alreadySeen
中已经检测过该 beanName
则直接返回 false
beanName
,由于多是别名,须要进行相关处理dependentBeanMap
中获取依赖 beanName
的 Bean 集合beanName
,也就不存在循环依赖,返回 false
beanName
的 Bean 们包含 dependentBeanName
,表示出现循环依赖,返回 true
beanName
的 Bean 们进行检查,看它们是否与 dependentBeanName
存在依赖,递归处理判断是否出现循环依赖的过程有点绕,须要花点时间理解一下。例如:如今检查 A ->(依赖)B,看是否出现循环依赖,我获取到依赖 A 的全部 Bean,看 B 是否依赖这里面的 Bean,若是出现 A -> B -> C -> A,那就出现循环依赖了。若是出现循环依赖,则会抛出异常,因此咱们说 Spring 处理了单例 Bean 的循环依赖注入比较好一点。
将 beanName
与 dep
(beanName
的依赖)之间依赖的关系进行缓存,调用 registerDependentBean(String beanName, String dependentBeanName)
方法,以下:
DefaultSingletonBeanRegistry.java public void registerDependentBean(String beanName, String dependentBeanName) { String canonicalName = canonicalName(beanName); // 对应关系:beanName -> 依赖 beanName 的集合 synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } // 对应关系:beanName - > beanName 的依赖的集合 synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } }
将二者的依赖关系保存起来,目的是在 isDependent
方法中判断是否出现循环依赖
加载 beanName
依赖的 Bean,一样是调用 AbstractBeanFactory#getBean(String dep)
方法,也就是本文开头讲的这个方法
Spring 的做用域划分为三种:单例模式、原型模式、其余模式,会依次进行判断,而后进行建立,建立过程都是同样的,主要是存储范围不同
request
做用域会将 Bean 存储在 ServletRequest 上下文中;session
做用域会将 Bean 存储在 HttpSession 中;application
做用域会将 Bean 存储在 ServletContext 中对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 if (mbd.isSingleton()) { // <9.1> 单例模式 /* * <9.1.1> 建立 Bean,成功建立则进行缓存,并移除缓存的早期对象 * 建立过程实际调用的下面这个 `createBean(...)` 方法 */ sharedInstance = getSingleton(beanName, // ObjectFactory 实现类 () -> { try { // **【核心】** 建立 Bean 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; } }); // <9.1.2> 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
若是是单例模式,建立过程大体以下:
调用 DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法
建立 Bean,成功建立则进行缓存,并移除缓存的早期对象,建立过程实际调用的下面这个 AbstractAutowireCapableBeanFactory#createBean(...)
方法
FactoryBean 的处理,在前面 3. FactoryBean 的处理 中已经分析过
DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法,单例模式下获取单例 Bean,以下:
// DefaultSingletonBeanRegistry.java public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); // 全局加锁 synchronized (this.singletonObjects) { // <1> 从 `singletonObjects` 单例 Bean 的缓存中获取 Bean(再检查一遍),存在则直接返回,不然开始建立 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> 将 `beanName` 标记为单例模式正在建立 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { /** * <3> 建立 Bean,实际调用 * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])} 方法 */ 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; } // <4> 将 `beanName` 标记为不在建立中,照应第 `2` 步 afterSingletonCreation(beanName); } // <5> 若是这里是新建立的单例模式 Bean,则在 `singletonObjects` 中进行缓存(无序),移除缓存的早期对象 // 并在 `registeredSingletons` 中保存 `beanName`,保证注册顺序 if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
过程大体以下:
singletonObjects
单例 Bean 的缓存中获取 Bean(再检查一遍),存在则直接返回,不然开始建立beanName
标记为单例模式正在建立AbstractAutowireCapableBeanFactory#createBean(...)
方法beanName
标记为不在建立中,照应第 2
步singletonObjects
中进行缓存(无序),移除缓存的早期对象,并在 registeredSingletons
中保存 beanName
,保证注册顺序AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法,建立 Bean,整个过程大体以下:
上面涉及到 Bean 生命周期的大部分阶段,将会在后续的文章中依次分析
对应代码段:
// AbstractBeanFactory.java // <9.2> 原型模式 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { // <9.2.1> 将 `beanName` 标记为**非单例模式**正在建立 beforePrototypeCreation(beanName); // <9.2.2> **【核心】** 建立 Bean prototypeInstance = createBean(beanName, mbd, args); } finally { // <9.2.3> 将 `beanName` 标记为不在建立中,照应第 `9.2.1` 步 afterPrototypeCreation(beanName); } // <9.2.4> 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); }
过程大体以下:
beanName
标记为非单例模式正在建立AbstractAutowireCapableBeanFactory#createBean(...)
方法,这里没有缓存,每次加载 Bean 都会建立一个对象beanName
标记为不在建立中,照应第 1
步对应代码段:
// AbstractBeanFactory.java // <9.3> 其余模式 else { // <9.3.1> 获取该模式的 Scope 对象 `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 { // <9.3.2> 从 `scope` 中获取 `beanName` 对应的对象(看你的具体实现),不存在则执行**原型模式**的四个步骤进行建立 Object scopedInstance = scope.get(beanName, () -> { // 将 `beanName` 标记为**非单例模式**式正在建立 beforePrototypeCreation(beanName); try { // **【核心】** 建立 Bean return createBean(beanName, mbd, args); } finally { // 将 `beanName` 标记为不在建立中,照应上一步 afterPrototypeCreation(beanName); } }); // 获取 Bean 的目标对象,`scopedInstance` 非 FactoryBean 类型直接返回 // 不然,调用 FactoryBean#getObject() 获取目标对象 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); } }
过程以下:
scope
,不存在则抛出异常scope
中获取 beanName
对应的对象(看你的具体实现),不存在则执行原型模式的四个步骤进行建立想要自定义一个做用域,能够实现 org.springframework.beans.factory.config.Scope
接口,并往 Spring 应用上下文注册便可
对应代码段:
// AbstractBeanFactory#doGetBean(...) 方法 // <10> 若是入参 `requiredType` 不为空,而且 Bean 不是该类型,则须要进行类型转换 if (requiredType != null && !requiredType.isInstance(bean)) { try { // <10.1> 经过类型转换机制,将 Bean 转换成 `requiredType` 类型 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); // <10.2> 转换后的 Bean 为空则抛出异常 if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } // <10.3> 返回类型转换后的 Bean 对象 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()); } }
若是入参 requiredType
不为空,而且 Bean 不是该类型,则须要进行类型转换,过程以下:
requiredType
类型,对 Spring 的类型转换机制感兴趣的小伙伴能够本身研究,参考 org.springframework.core.convert.support.DefaultConversionService
本文对 BeanFactory 接口的体系结构进行了分析,得知 DefaultListableBeanFactory 是 BeanFactory 的最底层实现,也就是 Spring 的底层 IoC 容器。接着分析了 AbstractBeanFactory
的 getBean(...)
方法,当咱们显示或者隐式地调用这个方法时,会触发 Bean 的加载。上面全部小节对 Bean 的加载过程进行了分析,我已经有序地在每一个小节面前添加了序号,这些序号对应着加载过程当中的顺序。
不一样做用域的 Bean 的建立,底层都会调用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法进行建立,建立 Bean 的过程涉及到 Bean 生命周期的大部分阶段,例如实例化阶段、属性赋值阶段、Aware 接口回调阶段、初始化阶段都是在这个方法中完成的,整个建立过程将在后续的文章进行分析。