缓存中没有获取到Bean实例会去走else分支,从零创建Bean实例
isPrototypeCurrentlyInCreation
用来判断当前Spring中,是否存在prototype类型的,且名称为beanName的bean正在创建。
prototype类型的bean实例,因为是没有缓存存放的,所以,一旦发现名称为beanName的bean正在创建,就会抛出异常来终止本次bean的创建。
获取RootBeanDefinition
getMergedLocalBeanDefinition
也有一个缓存mergedBeanDefinitions,它是用来存放beanName以及相应的BeanDefinition,同样的,初次到访缓存中也是什么都没有,也就是mbd为空。
而在调用getMergedBeanDefinition方法的同时也调用了方法getBeanDefinition,通过传入beanName来获取Spring容器中的BeanDefinition,看到这里,我们总算是等到了BeanDefinition发挥作用的时候了,也就是通过BeanDefinition中记录的bean的一系列信息,创建一个bean实例。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
getMergedBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException { synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; RootBeanDefinition previous = 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 || mbd.stale) { previous = mbd; if (bd.getParentName() == null) { // Use copy of given root bean definition. if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { //创建一个RootBeanDefinition对象封装原始的bd mbd = new RootBeanDefinition(bd); } } else { // Child bean definition: needs to be merged with parent. //获取父类的RootBeanDefinition对象 BeanDefinition pbd; try { //获取父类的实际BeanName String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { //递归调用getMergedBeanDefinition方法获取父类的RootBeanDefinition对象 pbd = getMergedBeanDefinition(parentBeanName); } //父类的BeanName和当前BeanName相同 else { //获取父类的BeanFactory BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { //去容器中获取RootBeanDefinition对象 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without a ConfigurableBeanFactory 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. //如果当前BeanDefinition对象的scope属性值为null,则设置为单例 if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(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); } } if (previous != null) { copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } }
- 通过创建一个
RootBeanDefinition
,封装从Spring容器中获取到的BeanDefinition
,因为容器中的BeanDefinition是GenericBeanDefinition
类型的,是没有记录父子bean标签的关系的,Spring在实例化前需要通过RootBeanDefinition来组织一下。
- 如果说当前的bean配置了父类bean,那就先封装父类bean的RootBeanDefinition,否则的话,直接封装当前bean对应的BeanDefinition即可。
- 将RootBeanDefinition中的类型设置为单例的,从这里就可以印证我们之前说的,也就是Spring中bean默认的类型就是单例的。
- 最后,Spring会将封装好的
RootBeanDefinition
添加到缓存中。