下面这张图演示了一个可用的Spring Bean是如何从xml配置文件中演变过来的
ps:配置元信息来源不仅可以在xml中,也可以在properties文件里以及注解元信息。
从上面的图中,我们可以比较清楚的知道Bean的元信息经过解析得到BeanDefinition,然后通过InstantiationStrategy策略将Class实例化为相应的Bean实例,此时该Bean实例字段均为空,然后经过一系列操作将一个可用的Bean实例提供出来供我们使用,在我们使用完之后,容器销毁时,将这些资源进行释放,最终有JVM进行垃圾回收。
b.Spring Bean生命周期概览图Spring内部IoC容器默认实现为:DefaultListableBeanFactory
Bean的生命周期与方法映射如下图所示:
三、Spring Bean生命周期核心方法 1、registerBeanDefinition-Spring Bean注册该方法定义于BeanDefinitionRegistry接口下,由DefaultListableBeanFactory提供具体实现,流程比较简单。
其实整个注册流程最核心的一段代码就是:this.beanDefinitionMap.put(beanName, beanDefinition);将相应的BeanDefinition注册到beanDefinitionMap中。key为baneName,value为BeanDefinition
// DefaultListableBeanFactory#registerBeanDefinition // 存储beanName(key)与BeanDefinition(value) private final Map2、getMergedBeanDefinition-Spring Bean合并beanDefinitionMap = new ConcurrentHashMap<>(256); // 存储beanName,实现容器BeanDefinition的顺序注册 private volatile List beanDefinitionNames = new ArrayList<>(256); // 是否允许相同名称不同BeanDefinition,后者覆盖前者 private boolean allowBeanDefinitionOverriding = true; //--------------------------------------------------------------------- // Implementation of BeanDefinitionRegistry interface //--------------------------------------------------------------------- @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { // <1> 对BeanDefinition的最后一次校验,主要对属性 methodOverrides 进行校验 ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } // <2>从缓存中拿BeanDefinition BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); // <2.1>如果缓存中有此BeanDefinition if (existingDefinition != null) { // 如果存在但是不允许覆盖,抛出异常 if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } // 覆盖 beanDefinition 大于 被覆盖的 beanDefinition 的 ROLE ,打印 info 日志 else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } // 覆盖 beanDefinition 与 被覆盖的 beanDefinition 不相同,打印 debug 日志 else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } // 其它,打印 trace 日志(很低的一种日志级别,一般不使用) else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } // 进行BeanDefinition覆盖 this.beanDefinitionMap.put(beanName, beanDefinition); } // <2.2>正常情况下,注册流程会走下面这个流程: else { // 检测Bean创建阶段已经开启,如果开启了就需要对BeanDefinitionMap进行并发控制(这里进行并发控制的原因我理解应该是:如果是Spring容器启动时是单线程的话,那么在注册阶段就不会出现Bean创建阶段的情况,既然出现了不同阶段同时进行的情况,那么一定是处于多线程的情况下,所以需要避免线程不安全的场景,所以需要加锁) if (hasBeanCreationStarted()) { // beanDefinitionMap是全局变量,需要进行并发控制,避免并发情况 // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { // 将BeanDefinition加入到beanDefinitionMap中 this.beanDefinitionMap.put(beanName, beanDefinition); // 将beanName加入到beanDefinitionNames中 List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; // 从 manualSingletonNames 移除 beanName, manualSingletonNames用于存储registerBeanDefinition外的单例注册bean removeManualSingletonName(beanName); } } else { // Still in startup registration phase // 将BeanDefinition加入到beanDefinitionMap中 this.beanDefinitionMap.put(beanName, beanDefinition); // 将beanName加入到beanDefinitionNames中 this.beanDefinitionNames.add(beanName); // 从 manualSingletonNames 移除 beanName, manualSingletonNames用于存储registerBeanDefinition外的单例注册bean removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } // 重新设置 beanName 对应的缓存 if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
该方法定义于ConfigurableBeanFactory接口下,由AbstractBeanFactory实现(考虑层次性容器)
此方法会返回一个BeanDefinition实例,如果当前Bean有parent指定,那么会返回一个父子合并后的BeanDefinition。
// AbstractBeanFactory#getMergedBeanDefinition private final Map3、resolveBeforeInstantiation 4、createBeanInstance 5、populateBean 6、initializeBean 7、preInstantiateSingletons 8、destroyBeanmergedBeanDefinitions = new ConcurrentHashMap<>(256); // 考虑层次性容器时会调用此方法(目前学习的过程当中还没有发现哪里有调用此方法) @Override public BeanDefinition getMergedBeanDefinition(String name) throws BeansException { //<1> 根据给定的name获得真正的beanName(有可能给定的name是别名) String beanName = transformedBeanName(name); // Efficiently check whether bean definition exists in this factory. //<2> 当前容器是否包含此BeanDefinition if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { // <2.1> 如果当前容器没有,并且父容器实例是ConfigurableBeanFactory,那么就去到父容器中去递归查找 return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName); } // Resolve merged bean definition locally. // <3> 获取当前容器的BeanDefinition return getMergedLocalBeanDefinition(beanName); } // AbstractBeanFactory#getMergedLocalBeanDefinition // 在spring执行doGetBean()方法时,调用的此方法 主要用于查找当前容器的BeanDefinition(不考虑层次性容器的场景) protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. // <1> 去到mergedBeanDefinitions中查找RootBeanDefinition信息 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); // <2> 如果找到了,并且当前mbd不允许重新合并时,直接返回(stale字段的含义就是决定BeanDefinition是否重新合并) if (mbd != null && !mbd.stale) { return mbd; } // <3> 重载方法,获取当前容器下父子Bean合并后的BeanDefinition return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } // AbstractBeanFactory#getMergedBeanDefinition protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { // <1> 重载方法(处理BeanDefinition合并的核心方法) return getMergedBeanDefinition(beanName, bd, null); } // AbstractBeanFactory#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 { mbd = new RootBeanDefinition(bd); } } else { // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try { 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(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; } }



