标签:eth meta 构造函数 sum eating 讲解 tty proxy lock
前言:经过前几篇文章的讲解,我们已经得到了BeanDefinition,接下来将分析Bean的加载。
获取Bean的入口:AbstractApplicationContext#getBean
1 public Object getBean(String name) throws BeansException { 2 // 检测bean工厂是否存活 3 assertBeanFactoryActive(); 4 return getBeanFactory().getBean(name); 5 }
分析:
首先检查BeanFactory是否存活,还记得之前分析过的prepareRefresh()方法吗?如果不记得了,请翻看之前的文章,那里设置了active的值,然后在这里做检查。如果BeanFactory关闭,则抛出异常。
1 protected void assertBeanFactoryActive() { 2 if (!this.active.get()) { 3 if (this.closed.get()) { 4 throw new IllegalStateException(getDisplayName() + " has been closed already"); 5 } else { 6 throw new IllegalStateException(getDisplayName() + " has not been refreshed yet"); 7 } 8 } 9 }
1 @Override 2 public Object getBean(String name) throws BeansException { 3 return doGetBean(name, null, null, false); 4 }
最终切入点:
1 // AbstractBeanFactory 2 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, 3 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { 4 5 // 返回bean名称,剥离工厂引用前缀 6 // 如果name是alias,则获取对应映射的beanName 7 final String beanName = transformedBeanName(name); 8 Object bean; 9 10 // 从缓存或实例工厂中获取Bean对象 11 // Eagerly check singleton cache for manually registered singletons. 12 Object sharedInstance = getSingleton(beanName); 13 if (sharedInstance != null && args == null) { 14 if (logger.isTraceEnabled()) { 15 if (isSingletonCurrentlyInCreation(beanName)) { 16 logger.trace("Returning eagerly cached instance of singleton bean ‘" + beanName + 17 "‘ that is not fully initialized yet - a consequence of a circular reference"); 18 } else { 19 logger.trace("Returning cached instance of singleton bean ‘" + beanName + "‘"); 20 } 21 } 22 // 完成FactoryBean的相关处理,并用来获取FactoryBean的处理结果 23 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 24 } else { 25 // Fail if we‘re already creating this bean instance: 26 // We‘re assumably within a circular reference. 27 // Spring只能解决单例模式下的循环依赖,在原型模式下如果存在循环依赖则抛出异常 28 // 这里检测原型模式下,该bean是否在加载,如果在加载则抛出异常 29 if (isPrototypeCurrentlyInCreation(beanName)) { 30 throw new BeanCurrentlyInCreationException(beanName); 31 } 32 33 // 如果当前容器中没有找到,则从父类容器中加载 34 // Check if bean definition exists in this factory. 35 BeanFactory parentBeanFactory = getParentBeanFactory(); 36 /** 37 * 调用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法 38 * 其实就是在beanDefinitionMap中判断是否存在beanName对应的BeanDefinition 39 */ 40 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 41 // Not found -> check parent. 42 // 确定原始的beanName 43 String nameToLookup = originalBeanName(name); 44 // 如果父类容器为AbstractBeanFactory,则委托父类处理 45 if (parentBeanFactory instanceof AbstractBeanFactory) { 46 return ((AbstractBeanFactory) parentBeanFactory).doGetBean( 47 nameToLookup, requiredType, args, typeCheckOnly); 48 } else if (args != null) { // 用明确的args从parentBeanFactory中,获取Bean对象 49 // Delegation to parent with explicit args. 50 // 委托给父类构造函数getBean()处理 51 return (T) parentBeanFactory.getBean(nameToLookup, args); 52 } else if (requiredType != null) { // 用明确的requiredType从parentBeanFactory中,获取Bean对象 53 // No args -> delegate to standard getBean method. 54 // 没有args,委托给标准的getBean()处理 55 return parentBeanFactory.getBean(nameToLookup, requiredType); 56 } else { 57 // 直接使用nameToLookup从parentBeanFactory中获取Bean对象 58 return (T) parentBeanFactory.getBean(nameToLookup); 59 } 60 } 61 62 // 如果不仅仅是做类型检查,而是创建bean,这里需要记录 63 if (!typeCheckOnly) { 64 markBeanAsCreated(beanName); 65 } 66 67 try { 68 /** 69 * 从容器中获取beanName对应的GenericBeanDefinition对象,并转换成RootBeanDefinition对象 70 * GenericBeanDefinition的创建{@link BeanDefinitionReaderUtils#createBeanDefinition}方法 71 */ 72 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 73 // 检查合并的BeanDefinition 74 checkMergedBeanDefinition(mbd, beanName, args); 75 76 // Guarantee initialization of beans that the current bean depends on. 77 // 处理所依赖的bean 78 String[] dependsOn = mbd.getDependsOn(); 79 if (dependsOn != null) { 80 for (String dep : dependsOn) { 81 // 若给定的依赖bean已经注册为依赖给定的bean 82 // 即循环依赖情况,抛出BeanCreationException异常 83 if (isDependent(beanName, dep)) { 84 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 85 "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘"); 86 } 87 // 缓存依赖调用 88 registerDependentBean(dep, beanName); 89 try { 90 // 递归处理依赖 Bean 91 getBean(dep); 92 } catch (NoSuchBeanDefinitionException ex) { 93 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 94 "‘" + beanName + "‘ depends on missing bean ‘" + dep + "‘", ex); 95 } 96 } 97 } 98 // bean实例化 99 // Create bean instance. 100 // 单例模式 101 /** 102 * 这里有个已创建bean的重要方法createBean 103 * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])} 104 */ 105 if (mbd.isSingleton()) { 106 sharedInstance = getSingleton(beanName, () -> { 107 try { 108 return createBean(beanName, mbd, args); 109 } catch (BeansException ex) { 110 // Explicitly remove instance from singleton cache: It might have been put there 111 // eagerly by the creation process, to allow for circular reference resolution. 112 // Also remove any beans that received a temporary reference to the bean. 113 // 显式从单例缓存中删除Bean实例 114 // 因为单例模式下为了解决循环依赖,可能它已经存在,所以销毁它 115 destroySingleton(beanName); 116 throw ex; 117 } 118 }); 119 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 120 } else if (mbd.isPrototype()) { // 原型模式 121 // It‘s a prototype -> create a new instance. 122 Object prototypeInstance = null; 123 try { 124 // 前置处理 125 beforePrototypeCreation(beanName); 126 /** 127 * 创建bean {@link AbstractAutowireCapableBeanFactory#createBean} 128 */ 129 prototypeInstance = createBean(beanName, mbd, args); 130 } finally { 131 /** 132 * 后置处理 与前置处理相反从{@link prototypesCurrentlyInCreation}中移除 133 */ 134 afterPrototypeCreation(beanName); 135 } 136 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 137 } else { //其他作用域 138 // 获得scopeName对应的Scope对象 139 String scopeName = mbd.getScope(); 140 final Scope scope = this.scopes.get(scopeName); 141 if (scope == null) { 142 throw new IllegalStateException("No Scope registered for scope name ‘" + scopeName + "‘"); 143 } 144 try { 145 /** 146 * 从指定的scope下创建bean 147 * {@link SimpleThreadScope#get方法} 148 */ 149 Object scopedInstance = scope.get(beanName, () -> { 150 beforePrototypeCreation(beanName); 151 try { 152 return createBean(beanName, mbd, args); 153 } finally { 154 afterPrototypeCreation(beanName); 155 } 156 }); 157 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 158 } catch (IllegalStateException ex) { 159 throw new BeanCreationException(beanName, 160 "Scope ‘" + scopeName + "‘ is not active for the current thread; consider " + 161 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 162 ex); 163 } 164 } 165 } catch (BeansException ex) { 166 cleanupAfterBeanCreationFailure(beanName); 167 throw ex; 168 } 169 } 170 171 // 检查需要的类型是否符合bean的实际类型 172 // Check if required type matches the type of the actual bean instance. 173 if (requiredType != null && !requiredType.isInstance(bean)) { 174 try { 175 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); 176 if (convertedBean == null) { 177 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 178 } 179 return convertedBean; 180 } catch (TypeMismatchException ex) { 181 if (logger.isTraceEnabled()) { 182 logger.trace("Failed to convert bean ‘" + name + "‘ to required type ‘" + 183 ClassUtils.getQualifiedName(requiredType) + "‘", ex); 184 } 185 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 186 } 187 } 188 return (T) bean; 189 }
分析:
这里的代码稍微有点多,但是这段代码非常重要,我们一步步来进行分析。
1 public String canonicalName(String name) { 2 String canonicalName = name; 3 // Handle aliasing... 4 String resolvedName; 5 // 循环,从aliasMap中获取最终的beanName 6 do { 7 resolvedName = this.aliasMap.get(canonicalName); 8 if (resolvedName != null) { 9 canonicalName = resolvedName; 10 } 11 } 12 while (resolvedName != null); 13 return canonicalName; 14 } 15 16 // BeanFactoryUtils 17 public static String transformedBeanName(String name) { 18 Assert.notNull(name, "‘name‘ must not be null"); 19 20 // 如果beanName不是以"&"开始,则直接返回 21 if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { 22 return name; 23 } 24 // computeIfAbsent方法,分两种情况: 25 // #1.不存在,则执行后面的lambda表达式,beanName的值就是name的值,并将结果添加到缓存。 26 // #2.存在,则直接返回name的值。 27 return transformedBeanNameCache.computeIfAbsent(name, beanName -> { 28 do { 29 beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); 30 } 31 while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); 32 return beanName; 33 }); 34 }
分析:
transformedBeanName函数的功能:返回beanName,剥离工厂引用前缀。
在BeanFactoryUtils#transformedBeanName中:
1 protected Object getSingleton(String beanName, boolean allowEarlyReference) { 2 // 从单例缓存中加载Bean 3 Object singletonObject = this.singletonObjects.get(beanName); 4 // 缓存中bean为空,且当前bean正在创建 5 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { 6 // 做同步 7 synchronized (this.singletonObjects) { 8 // 从earlySingletonObjects集合中获取 9 singletonObject = this.earlySingletonObjects.get(beanName); 10 // earlySingletonObjects集合中没有,其允许提前创建 11 if (singletonObject == null && allowEarlyReference) { 12 // 从singletonFactories中获取对应的ObjectFactory 13 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); 14 if (singletonFactory != null) { 15 // 获取bean 16 singletonObject = singletonFactory.getObject(); 17 // 将bean添加到earlySingletonObjects集合中 18 this.earlySingletonObjects.put(beanName, singletonObject); 19 // 从singletonFactories中移除对应的 20 this.singletonFactories.remove(beanName); 21 } 22 } 23 } 24 } 25 return singletonObject; 26 }
分析:
在加载bean时,首先从单例缓存中获取bean对象。
注意这里涉及到三个集合:
1 /** 2 * Cache of singleton objects: bean name to bean instance. 3 * 存放的是单例 bean 的映射。 4 * <p> 5 * 对应关系为 bean name --> bean instance 6 */ 7 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 8 9 /** 10 * Cache of singleton factories: bean name to ObjectFactory.<br/> 11 * 存放的是 ObjectFactory,可以理解为创建单例 bean 的 factory 。 12 * <p> 13 * 对应关系是 bean name --> ObjectFactory 14 */ 15 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); 16 17 /** 18 * Cache of early singleton objects: bean name to bean instance.<br/> 19 * 存放的是早期的 bean,对应关系也是 bean name --> bean instance。 20 * <p> 21 * 它与 {@link #singletonFactories} 区别在于 earlySingletonObjects 中存放的 bean 不一定是完整。 22 * <p> 23 * 从 {@link #getSingleton(String)} 方法中,我们可以了解,bean 在创建过程中就已经加入到 earlySingletonObjects 中了。 24 * 所以当在 bean 的创建过程中,就可以通过 getBean() 方法获取。 25 * <p> 26 * 这个 Map 也是【循环依赖】的关键所在。 27 */ 28 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
这三个缓存集合就是解决Spring中循环依赖的所在,具体流程:
如果从单例缓存中得到bean对象,则会调用getObjectForBeanInstance方法进一步处理,因为从缓存中得到的bean是最原始的bean,并不一定是最终所需要的bean对象。
1 protected Object getObjectForBeanInstance( 2 Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { 3 4 String currentlyCreatedBean = this.currentlyCreatedBean.get(); 5 if (currentlyCreatedBean != null) { 6 registerDependentBean(beanName, currentlyCreatedBean); 7 } 8 9 return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd); 10 }
分析:
1 protected Object getObjectForBeanInstance( 2 Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { 3 4 // 如果name是工厂类的引用名称(name以"&"开头) 5 // Don‘t let calling code try to dereference the factory if the bean isn‘t a factory. 6 if (BeanFactoryUtils.isFactoryDereference(name)) { 7 // 如果是NullBean则直接返回 8 if (beanInstance instanceof NullBean) { 9 return beanInstance; 10 } 11 // 如果beanInstance不是FactoryBean则抛出异常 12 if (!(beanInstance instanceof FactoryBean)) { 13 throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); 14 } 15 } 16 17 // 走到这里,说明我们现在已经有一个Bean实例,当然该实例可能会是一个正常的Bean或者又是一个FactoryBean 18 // 如果是FactoryBean,则创建Bean 19 // Now we have the bean instance, which may be a normal bean or a FactoryBean. 20 // If it‘s a FactoryBean, we use it to create a bean instance, unless the 21 // caller actually wants a reference to the factory. 22 // 如果beanInstance不是Factory或者beanName以&开头,则直接返回 23 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { 24 return beanInstance; 25 } 26 27 Object object = null; 28 // 若BeanDefinition为null,则从缓存中加载bean对象 29 if (mbd == null) { 30 object = getCachedObjectForFactoryBean(beanName); 31 } 32 // 如果Object仍然为空,则可以确认beanInstance一定是FactoryBean。从而使用FactoryBean获取Bean对象 33 // 通过beanInstance instanceof FactoryBean这里判断,如果beanInstance不是FactoryBean已经直接返回了 34 if (object == null) { 35 // Return bean instance from factory. 36 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; 37 // 检测beanDefinitionMap中,也就是所有已加载的类中是否定义了beanName 38 // Caches object obtained from FactoryBean if it is a singleton. 39 if (mbd == null && containsBeanDefinition(beanName)) { 40 // 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition 41 // 如果指定beanName是子Bean的话同时会合并父类的相关属性 42 mbd = getMergedLocalBeanDefinition(beanName); 43 } 44 // 是否是用户定义的,而不是程序本身定义的 45 boolean synthetic = (mbd != null && mbd.isSynthetic()); 46 // 核心函数,使用FactoryBean获得Bean对象 47 object = getObjectFromFactoryBean(factory, beanName, !synthetic); 48 } 49 return object; 50 }
分析:
AbstractBeanFactory#getMergedLocalBeanDefinition
1 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { 2 // Quick check on the concurrent map first, with minimal locking. 3 // 快速从缓存中获取,如果不为null,则直接返回 4 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 5 if (mbd != null) { 6 return mbd; 7 } 8 // 获取RootBeanDefinition,如果返回的BeanDefinition是子类的bean的话,则合并父类相关属性 9 // getBeanDefinition函数从beanDefinitionMap中取出对应的BeanDefinition 10 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 11 }
分析:
AbstractBeanFactory#getMergedBeanDefinition
1 protected RootBeanDefinition getMergedBeanDefinition( 2 String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 3 throws BeanDefinitionStoreException { 4 // 做同步 5 synchronized (this.mergedBeanDefinitions) { 6 RootBeanDefinition mbd = null; 7 // 如果containingBd为null,则从mergedBeanDefinitions中尝试获取 8 // Check with full lock now in order to enforce the same merged instance. 9 if (containingBd == null) { 10 mbd = this.mergedBeanDefinitions.get(beanName); 11 } 12 // 如果集合中不存在RootBeanDefinition 13 if (mbd == null) { 14 // 并且无父类 15 if (bd.getParentName() == null) { 16 // 如果BeanDefinition是RootBeanDefinition类型,则直接拷贝 17 // Use copy of given root bean definition. 18 if (bd instanceof RootBeanDefinition) { 19 mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); 20 } else { 21 // 否则新创建一个RootBeanDefinition对象 22 mbd = new RootBeanDefinition(bd); 23 } 24 } else { 25 // 如果存在父类 26 // Child bean definition: needs to be merged with parent. 27 BeanDefinition pbd; 28 try { 29 // 首先获取父类的beanName 30 String parentBeanName = transformedBeanName(bd.getParentName()); 31 // beanName与父类beanName不相等 32 if (!beanName.equals(parentBeanName)) { 33 // 通过父类beanName返回BeanDefinition 34 pbd = getMergedBeanDefinition(parentBeanName); 35 } else { 36 BeanFactory parent = getParentBeanFactory(); 37 if (parent instanceof ConfigurableBeanFactory) { 38 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); 39 } else { 40 throw new NoSuchBeanDefinitionException(parentBeanName, 41 "Parent name ‘" + parentBeanName + "‘ is equal to bean name ‘" + beanName + 42 "‘: cannot be resolved without an AbstractBeanFactory parent"); 43 } 44 } 45 } catch (NoSuchBeanDefinitionException ex) { 46 throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, 47 "Could not resolve parent bean definition ‘" + bd.getParentName() + "‘", ex); 48 } 49 // Deep copy with overridden values. 50 mbd = new RootBeanDefinition(pbd); 51 mbd.overrideFrom(bd); 52 } 53 54 // Set default singleton scope, if not configured before. 55 if (!StringUtils.hasLength(mbd.getScope())) { 56 mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); 57 } 58 59 // A bean contained in a non-singleton bean cannot be a singleton itself. 60 // Let‘s correct this on the fly here, since this might be the result of 61 // parent-child merging for the outer bean, in which case the original inner bean 62 // definition will not have inherited the merged outer bean‘s singleton status. 63 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { 64 mbd.setScope(containingBd.getScope()); 65 } 66 67 // Cache the merged bean definition for the time being 68 // (it might still get re-merged later on in order to pick up metadata changes) 69 if (containingBd == null && isCacheBeanMetadata()) { 70 this.mergedBeanDefinitions.put(beanName, mbd); 71 } 72 } 73 74 return mbd; 75 } 76 }
分析(注意给方法是同步的,Spring中很多这种同步方法):
1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { 2 // 为单例模式,其缓存中存在该bean实例 3 if (factory.isSingleton() && containsSingleton(beanName)) { 4 /** 5 * 做同步,内部其实使用的就是{@link DefaultSingletonBeanRegistry#singletonObjects} 6 */ 7 synchronized (getSingletonMutex()) { 8 // 从缓存中获取指定的factoryBean 9 Object object = this.factoryBeanObjectCache.get(beanName); 10 if (object == null) { 11 // 为空,则从FactoryBean中获取对象 12 object = doGetObjectFromFactoryBean(factory, beanName); 13 // Only post-process and store if not put there already during getObject() call above 14 // (e.g. because of circular reference processing triggered by custom getBean calls) 15 // 再次从缓存中获取bean对象,主要是因为循环依赖 16 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); 17 if (alreadyThere != null) { 18 object = alreadyThere; 19 } else { 20 // 需要后续处理 21 if (shouldPostProcess) { 22 // 如果该Bean处于创建中,则返回非处理对象,而不是存储该对象 23 if (isSingletonCurrentlyInCreation(beanName)) { 24 // Temporarily return non-post-processed object, not storing it yet.. 25 return object; 26 } 27 // 单例bean的前置处理 用于添加标志,当前bean正处于创建中 28 beforeSingletonCreation(beanName); 29 try { 30 // 对FactoryBean获取的对象进行后置处理,返回生成的对象 31 object = postProcessObjectFromFactoryBean(object, beanName); 32 } catch (Throwable ex) { 33 throw new BeanCreationException(beanName, 34 "Post-processing of FactoryBean‘s singleton object failed", ex); 35 } finally { 36 // 单例bean的后置处理 和前置处理相反,前置添加,后置移除 移除标志,当前bean不处于创建中 37 afterSingletonCreation(beanName); 38 } 39 } 40 // 添加到factoryBeanObjectCache中进行缓存 41 if (containsSingleton(beanName)) { 42 this.factoryBeanObjectCache.put(beanName, object); 43 } 44 } 45 } 46 return object; 47 } 48 } else { 49 // 不满足第一个条件,不是单例,或者缓存中不存在,则从FactoryBean中获取对象 50 Object object = doGetObjectFromFactoryBean(factory, beanName); 51 // 需要后续处理 52 if (shouldPostProcess) { 53 try { 54 // 对FactoryBean获取的对象进行后处理 55 // 返回生成的对象 56 object = postProcessObjectFromFactoryBean(object, beanName); 57 } catch (Throwable ex) { 58 throw new BeanCreationException(beanName, "Post-processing of FactoryBean‘s object failed", ex); 59 } 60 } 61 return object; 62 } 63 }
由于篇幅原因该函数将在后续文章中继续分析,文章太长笔者认为不宜阅读。
本文才进入加载bean的流程,从单例缓存中获取单例bean对象,后续继续强行开撸。
by Shawn Chen,2019.04.20,上午。
标签:eth meta 构造函数 sum eating 讲解 tty proxy lock
原文地址:https://www.cnblogs.com/developer_chan/p/10723911.html