Spring-beanFactory
Spring BeanFactory
- Author: HuiFer
- 源码阅读仓库: SourceHot-spring
BeanFactory 概述
- org.springframework.beans.factory.BeanFactory
类图
         
   
    
方法列表
- 贴出部分代码. 仅表示方法作用
|  |  | 
解析
用例
bean 的实例化有如下几种方法
- 静态方法
- 工厂方法创建
- FactoryBean 接口创建
代码部分
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
分析
- 对下面代码进行分析
|  |  | 
- org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String, java.lang.Class<T>)
|  |  | 
- 从方法参数
- name: beanName
- requiredType: 唯一的类型. 对象类型
 
assertBeanFactoryActive
- beanFactory 是否存活判断
|  |  | 
getBeanFactory
- 
获取 beanFactory - 
获取方法是一个抽象方法 1public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;- 
子类实现 org.springframework.context.support.AbstractRefreshableApplicationContext#getBeanFactory1 2 3 4 5 6 7 8 9 10@Override public final ConfigurableListableBeanFactory getBeanFactory() { synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }- org.springframework.context.support.GenericApplicationContext#getBeanFactory
 1 2 3 4@Override public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; }
 
- 
 
- 
- 
获取到的对象是 org.springframework.beans.factory.support.DefaultListableBeanFactory
         
   
    
- 整体类图
         
   
    
doGetBean
- 
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean获取 bean 的核心 
transformedBeanName
|  |  | 
|  |  | 
|  |  | 
别名对象
|  |  | 
|  |  | 
aliasMap 和 别名标签的对应关系
         
   
    
alias 标签的 alias 值作为别名的 key , alias 标签的 name 值作为 value
getSingleton
- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
|  |  | 
- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
|  |  | 
- 相关属性值
|  |  | 
getObjectForBeanInstance
- org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
|  |  | 
getObjectFromFactoryBean
- 
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
- 
从 FactoryBean 中获取对象 
|  |  | 
beforeSingletonCreation
- 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
- 
单例创建前的验证 
|  |  | 
postProcessObjectFromFactoryBean
- 
两种实现 - 
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#postProcessObjectFromFactoryBean1 2 3protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException { return object; }直接返回 object 
- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean调用BeanPostProcessor1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20@Override protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
 
- 
- 
两个方法军返回 Bean对象 . 一种是直接返回 。 另一种是执行接口BeanPostProcessor接口返回
afterSingletonCreation
- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation
|  |  | 
- 代码现在进入的很深了,回到 doGetBean
- org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
|  |  | 
- 
目前未知 doGetBean的第一个if分支已经分析完毕. 接下来看下面的代码
- 
下面这段代码就简单说一下就跳过了。 - 从 容器中获取,最后还是回到 doGetBean 方法中. 来进行 bean 创建 这里不进行展开。
 
|  |  | 
markBeanAsCreated
- 
org.springframework.beans.factory.support.AbstractBeanFactory#markBeanAsCreated
- 
方法作用将 bean 标记为已创建 
protected void markBeanAsCreated(String beanName) {
   // 已创建的beanName 是否包含当前beanName
   if (!this.alreadyCreated.contains(beanName)) {
      synchronized (this.mergedBeanDefinitions) {
         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.
            // 将属性stale设置true
            clearMergedBeanDefinition(beanName);
            // 放入已创建集合中
            this.alreadyCreated.add(beanName);
         }
      }
   }
}
|  |  | 
- 
stale 的解释 1 2 3 4 5/** * Determines if the definition needs to be re-merged. * 是否需要重新合并定义 * */ volatile boolean stale;
- 
属性值 已创建的 beanName 1private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
getMergedLocalBeanDefinition
- 
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
- 
这个方法获取一个 RootBeanDefinition对象 , 这个对象也是 bean 的一种定义。
- 
从目前的几个方法名称来看,暂且认为这是一个合并了多个 BeanDefinition的对象吧
         
   
    
|  |  | 
getBeanDefinition
- 获取 beanDefinition
- org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanDefinition
|  |  | 
- 
从 beanDefinition map 中获取 
- 
相关属性 1 2 3 4 5 6 7 8/** * Map of bean definition objects, keyed by bean name. * * key: beanName * value: BeanDefinition * * */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
getMergedBeanDefinition
- 
获取 RootBeanDefinition
- 
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)
- 
第一部分代码 - map 中获取 RootBeanDefinition
- 是否存在父名称
- 类型是否是 RootBeanDefinition- 是: 拷贝
- 否: 将 BeanDefinition转换成RootBeanDefinition
 
 
|  |  | 
- 
相关属性 1 2 3 4 5 6/** * Map from bean name to merged RootBeanDefinition. * key: beanName * value: RootBeanDefinition * */ private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
- 
克隆 方法 1 2 3 4 5 6 7 8/** * 克隆 BeanDefinition * @return */ @Override public RootBeanDefinition cloneBeanDefinition() { return new RootBeanDefinition(this); }
- 
第二部分代码 
|  |  | 
overrideFrom
- 
覆盖方法 
- 
org.springframework.beans.factory.support.AbstractBeanDefinition#overrideFrom
- 
最后一段 
|  |  | 
checkMergedBeanDefinition
- 
org.springframework.beans.factory.support.AbstractBeanFactory#checkMergedBeanDefinition1 2 3 4 5 6 7protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args) throws BeanDefinitionStoreException { if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } }- 判断是否 abstract 标记的情况
 
- 
继续回到 doGetBean方法
|  |  | 
isDependent
- 
是否存在依赖关系 
- 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isDependent(java.lang.String, java.lang.String, java.util.Set<java.lang.String>)
|  |  | 
- 
相关属性 1 2 3 4 5 6 7/** * Map between dependent bean names: bean name to Set of dependent bean names. * * key: bean * value: 依赖列表 * */ private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
- 
一个用例 
|  |  | 
         
   
    
registerDependentBean
- 注册依赖关系
- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerDependentBean- 在前文调用 isDependent方法的的时候我们找到了一个依赖映射dependentBeanMap,在这个方法中会将依赖关系放入dependentBeanMap
 
- 在前文调用 
|  |  | 
- 
再回到 doGetBean
- 
接下来就是实例化的过程了. 
|  |  | 
getSingleton
- 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
- 
获取单例对象 - 从单例对象的 map 缓存中获取
- 从 ObjectFactory 中获取
 
- 
周边方法 - 
beforeSingletonCreation
- 
afterSingletonCreation
- 
addSingleton
 
- 
|  |  | 
- 
回到 doGetBean 方法中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16if (mbd.isSingleton()) { // 判断是否是单例 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; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }这里又要给 createBean方法, 从getSingleton的参数看可以知道 ,第二个匿名函数是ObjectFactory接口实现.1 2 3 4 5 6 7 8 9 10 11 12 13@FunctionalInterface public interface ObjectFactory<T> { /** * Return an instance (possibly shared or independent) * of the object managed by this factory. * 获取对象 * @return the resulting instance * @throws BeansException in case of creation errors */ T getObject() throws BeansException; }- createBean 返回的就是单例 bean 对象的实例
 
createBean
- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
- 
两个核心方法 
|  |  | 
resolveBeforeInstantiation
- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
- 
方法概述: 获取 BeanPostProcessor接口的实现列表- applyBeanPostProcessorsBeforeInstantiation前置方法执行
- applyBeanPostProcessorsAfterInitialization后置方法执行
 
|  |  | 
doCreateBean
- 创建 bean
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
|  |  | 
createBeanInstance
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
- 创建 bean 实例
|  |  | 
resolveBeanClass
- org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
- 获取 bean 的 class
|  |  | 
doResolveBeanClass
- 
org.springframework.beans.factory.support.AbstractBeanFactory#doResolveBeanClass
- 
第一段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23ClassLoader beanClassLoader = getBeanClassLoader(); ClassLoader dynamicLoader = beanClassLoader; boolean freshResolve = false; // 判断 typesToMatch 是否为空 if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). // 获取临时类加载器 ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { dynamicLoader = tempClassLoader; freshResolve = true; // 类型比较 if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class<?> typeToMatch : typesToMatch) { // 添加排除的类 dcl.excludeClass(typeToMatch.getName()); } } } }
- 
第二段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16if (className != null) { // bean 属性值 Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) { // A dynamically resolved expression, supported as of 4.2... if (evaluated instanceof Class) { return (Class<?>) evaluated; } else if (evaluated instanceof String) { className = (String) evaluated; freshResolve = true; } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } }
evaluateBeanDefinitionString
|  |  | 
evaluate
- org.springframework.context.expression.StandardBeanExpressionResolver#evaluate
|  |  | 
- 类图
         
   
    
BeanExpressionContext
- 两个属性
|  |  | 
- 几个方法
|  |  | 
beanName 是否存在
根据 beanName 获取 bean 实例
- 回到解析方法
parseExpression
|  |  | 
- 
doParseExpression - spring 中的两种解析方式
- org.springframework.expression.spel.standard.InternalSpelExpressionParser#doParseExpression
- org.springframework.expression.spel.standard.SpelExpressionParser#doParseExpression
 
 
- spring 中的两种解析方式
- 
parseTemplate 方法 - org.springframework.expression.common.TemplateAwareExpressionParser#parseTemplate
 
|  |  | 
         
   
    
- 
parseExpressions- org.springframework.expression.common.TemplateAwareExpressionParser#parseExpressions
- 说简单一些这个地方就是拿出表达式的值
 
- 
回到 evaluate方法
|  |  | 
- 
最后一句 getValue- 
org.springframework.expression.common.LiteralExpression#getValue(org.springframework.expression.EvaluationContext)刚才流程中我们可以看到 expr是LiteralExpression1 2 3 4@Override public String getValue(EvaluationContext context) { return this.literalValue; }直接返回字符串. 这个字符串就是刚才放进去的 el 表达式 
 
- 
往外跳 找到方法 doResolveBeanClass
|  |  | 
- 目前为止我们解析了 第一句话 Object evaluated = evaluateBeanDefinitionString(className, mbd);接下来往下走看一下具体的 class 返回对象
- 类型等于 class 直接返回
- 类型等于 String 的两种返回方式
- ClassLoader.loadClass 返回
- ClassUtils.forName 返回
- 底层方法为 java.lang.Class#forName(java.lang.String, boolean, java.lang.ClassLoader)
 
- 底层方法为 
 
resolveBeanClass
- 
回到 doResolveBeanClass方法中.最后一行1 2// Resolve regularly, caching the result in the BeanDefinition... return mbd.resolveBeanClass(beanClassLoader);
|  |  | 
- 获取 beanClassName
|  |  | 
- 回到createBeanInstance- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
 
|  |  | 
obtainFromSupplier
|  |  | 
- Supplier代码如下
|  |  | 
initBeanWrapper
|  |  | 
registerCustomEditors
|  |  | 
- 
最后调用 org.springframework.beans.support.ResourceEditorRegistrar#registerCustomEditors
registerCustomEditors
|  |  | 
doRegisterEditor
|  |  | 
覆盖默认编辑器
|  |  | 
- registerCustomEditor
|  |  | 
到这里 createBeanInstance 流程已经完毕
回到doCreateBean 方法
|  |  | 
紧接着两行代码 获取 bean 实例 和 beanType
applyMergedBeanDefinitionPostProcessors
|  |  | 
- applyMergedBeanDefinitionPostProcessors方法会执行所有的后置方法.
|  |  | 
addSingletonFactory
- 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
- 
继续回到 doCreateBean 
|  |  | 
- 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory添加单例工厂 
|  |  | 
getEarlyBeanReference
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
|  |  | 
- wrapIfNecessary
|  |  | 
- 
回到下面代码中 1 2 3 4 5 6 7 8if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 添加单例工厂 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }- 上述方法就是将结果 bean 放入
 
populateBean
|  |  | 
- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
- 
设置属性值 
- 
概述一下方法 - 
自动注入的两种实现 - 根据类型
- 根据名称
 
- 
xml 中的属性标签设置 1 2 3<bean class="org.source.hot.spring.overview.ioc.bean.init.UserBean"> <property name="age" value="30"/> </bean>
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83{ if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 获取自动注入的值 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 自动注入 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { // 按照名称注入 autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // 按照类型注入 autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 以来检查 checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 应用属性 applyPropertyValues(beanName, mbd, bw, pvs); } }
- 
pvs 属性如下
         
   
    
applyPropertyValues
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
- 属性设置
|  |  | 
属性设置后跳出方法回到 doCreateBean
|  |  | 
         
   
    
initializeBean
- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
- 
我们可以看一下整个代码的流程 - aware 接口的执行
- BeanPostProcessor 前置方法执行
- bean 实例化
- BeanPostProcessor 后置方法执行
- 返回 bean
 
|  |  | 
- Aware 接口的执行
|  |  | 
- 
前置方法执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
- 
后置方法执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { // 执行 spring 容器中 BeanPostProcessor Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
invokeInitMethods
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
- 初始化方法重点看一下
|  |  | 
         
   
    
我们现在的 bean 不是InitializingBean 会走自定义的init-mthod方法
- 
做一下改造实体对象 1 2 3 4public void initMethod() { this.name = "abc"; this.age = 10; }
|  |  | 
- 观察 initMethodName会变成 标签属性init-method的内容. 接下来就是通过反射执行方法
         
   
    
- 
在执行方法前将 bean 的信息先做一次截图   
- 
如果按照我们代码中的编写方式 bean 的属性会被覆盖   
invokeCustomInitMethod
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeCustomInitMethod
- 执行 自定义的init-method方法
|  |  | 
getInterfaceMethodIfPossible
- org.springframework.util.ClassUtils#getInterfaceMethodIfPossible
|  |  | 
- 
跳出这个方法 initializeBean回到下面代码1 2 3 4try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); }- 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean其实到此 bean 已经创建完成可以直接返回了. 
 
- 
- 
再往外层跳 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16if (mbd.isSingleton()) { // 判断是否是单例 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; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }- 单例对象的创建 bean 已经完成啦…
 
- 
其他的两种创建,其本质还是 createBean方法的调用.
|  |  | 
- 
再往外面跳一层 回到 getBean 方法. 
- 
终于 getBean 方法底层调用分析结束. 
- 原文作者:知识铺
- 原文链接:https://geek.zshipu.com/post/code/docs/Spring/clazz/Spring-beanFactory/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com
 
                
             
                
            