refresh() -> finishBeanFactoryInitialization()

refresh() -> finishBeanFactoryInitialization()

初始化剩下的单实例(非懒加载的)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  // Initialize conversion service for this context.
  // 为上下文初始化类型转换器
  if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
      beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
    beanFactory.setConversionService(
      beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  }

  // Register a default embedded value resolver if no bean post-processor
  // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  // at this point, primarily for resolution in annotation attribute values.
  // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
  if (!beanFactory.hasEmbeddedValueResolver()) {
    beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  }

  // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
  // 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
  String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  for (String weaverAwareName : weaverAwareNames) {
    getBean(weaverAwareName);
  }

  // Stop using the temporary ClassLoader for type matching.
  // 禁止使用临时类加载器进行类型匹配
  beanFactory.setTempClassLoader(null);

  // Allow for caching all bean definition metadata, not expecting further changes.
  // 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
  beanFactory.freezeConfiguration();

  // Instantiate all remaining (non-lazy-init) singletons.
  // 实例化剩下的单例对象
  beanFactory.preInstantiateSingletons();
}

1.为上下文初始化类型转换器

ConversionService

转换服务:如未设置则没有该转换服务对象,如配置了,则默认为DefaultConversionService

引入方式
<bean id="conversionService"
    class="org.springframework.context.support.ConversionServiceFactoryBean"/>

可以在ConversionServiceFactoryBean实例中引入自定义的转换对象

<bean id="conversionService"
        class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="example.MyCustomConverter"/>
        </set>
    </property>
</bean>
DefaultConversionService

默认设置了52种转换方式,有一对一的转换,一对多的转换,多对多的转换,分别如下

  • 一转一:实现Converter接口

    public interface Converter<S, T> {
    	// 将S类型转换成T类型
    	T convert(S source);
    }
    
  • 一转多:实现GenericConverter接口(用于两种或者更多种类型之间转换的通用转换器接口)

    // 转换源对象到目标类型的描述
    Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
    
  • 多转多:实现ConverterFactory接口(converter转换器的工厂类,用来获取对应的转换器)

    public interface ConverterFactory<S, R> {
    	// 获取转换器
    	<T extends R> Converter<S, T> getConverter(Class<T> targetType);
    }
    
  • ConditionalConverter:根据sourcetarget来做条件判断,从而判断哪个转换器生效哪个转换器不生效

    boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
    

2.判断beanFactory之前没有注册嵌入值解析器,没有则注册

PropertyPlaceholderConfigurer主要用于注解属性值的解析

通常在invokeBeanFactoryPostProcessors()方法中就已经注册了,所以这里无需再注册

3.初始化loadTimeWeaverAware bean

// 默认没有
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);

AOP部分详细讲解

4.禁止使用临时类加载器进行类型匹配

设置BeanFactorytempClassLoader属性为null

public void setTempClassLoader(@Nullable ClassLoader tempClassLoader) {
  this.tempClassLoader = tempClassLoader;
}

5.冻结所有的bean定义

设置BeanFactoryconfigurationFrozen属性为true,且赋值属性frozenBeanDefinitionNames字符数组为BeanFactory中的beanDefinitionNames属性值

public void freezeConfiguration() {
   this.configurationFrozen = true;
   this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

备注:此处说明注册的bean定义将不被修改或任何进一步的处理

6.实例化剩下的单例对象

beanFactory.preInstantiateSingletons();

DefaultListableBeanFactory

	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		// 将所有BeanDefinition的名字创建一个集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 触发所有非延迟加载单例bean的初始化,遍历集合的对象
		for (String beanName : beanNames) {
			// 合并父类BeanDefinition
 			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 条件判断,抽象,单例,非懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
					// 根据&+beanName来获取具体的对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 进行类型转换
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						// 判断这个FactoryBean是否希望立即初始化
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//  如果希望急切的初始化,则通过beanName获取bean实例
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
		for (String beanName : beanNames) {
			// 获取beanName对应的bean实例
			Object singletonInstance = getSingleton(beanName);
			// 判断singletonInstance是否实现了SmartInitializingSingleton接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				// 类型转换
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				// 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

getMergedLocalBeanDefinition

在实例化之前,要把所有的基础的BeanDefinition对象转换成RootBeanDefinition对象,进行缓存,后续在需要马上要实例化的时候,直接获取定义信息,而定义信息中如果包含了父类,那么必须要先创建父类才能有子类

// 获取beanName合并后的本地RootBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
  // Quick check on the concurrent map first, with minimal locking.
  // 首先以最小的锁定快速检测并发映射。
  // 从bean名称映射到合并的RootBeanDefinition的集合中获取beanName对应的RootBeanDefinition
  RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
  // 如果mbd不为null 且 不需要重新合并定义
  if (mbd != null && !mbd.stale) {
    // 返回对应的RootBeanDefinition
    return mbd;
  }
  // 获取beanName对应的合并Bean定义,如果beanName对应的BeanDefinition是子BeanDefinition,
  // 则通过与父级合并返回RootBeanDefinition
  return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

mergedBeanDefinitions
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);

该集合对象前期部分BeanDefinition对象由于场景需要已经合并为了RootBeanDefinition对象且缓存到了该集合中,如:refresh() -> invokeBeanFactoryPostProcessors()

  1. org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
  2. org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType
  3. org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType
  4. org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition

isFactoryBean

确定nameBean是否为FactoryBean

public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
   //去除name开头的'&'字符,获取name最终的规范名称【最终别名或者是全类名】:
   String beanName = transformedBeanName(name);
   //获取beanName注册的(原始)单例对象,如果单例对象没有找到,并且beanName存在
   //     正在创建的Set集合中
   Object beanInstance = getSingleton(beanName, false);
   //如果beanInstance能获取到
   if (beanInstance != null) {
      // 如果 beanInstance是FactoryBean的实例 则返回true,否则返回false。
      return (beanInstance instanceof FactoryBean);
   }
   // No singleton instance found -> check bean definition.
   // 如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // No bean definition found in this factory -> delegate to parent.
      // 在该工厂中找不到bean定义 -> 委托给父对象
      // 尝试在父工厂中确定name是否为FactoryBean,如果不是返回false,否则返回true【递归】
      return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
   }
   // 如果该bean对应于子bean定义,则遍历父bean定义。
   // 判断(beanName和beanName对应的合并后BeanDefinition)所指的bean是否FactoryBean并将结果返回出去
   return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
isFactoryBean
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
   // 定义一个存储mbd是否是FactoryBean的标记
   Boolean result = mbd.isFactoryBean;
   // 如果没有配置mbd的工厂Bean
   if (result == null) {
      // 根据预测指定bean的最终bean类型
      Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
      // 如果成功获取最终bean类型,且最终bean类型属于FactoryBean类型
      result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
      // 将result缓存在mbd中
      mbd.isFactoryBean = result;
   }
   // 如果不为空,直接返回
   return result;
}

getBean

此方法不仅在此处会调用,在执行finishBeanFactoryInitialization()方法前就已经调用过。如:invokeBeanFactoryPostProcessors()中就调用该方法进行对象的实例化

实例化简要概述
  1. getBean
  2. doGetBean:此方法是实际获取bean的方法,也是触发依赖注入的方法
  3. createBean
  4. doCreateBean
doGetBean
protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {

   /**
    * 提取对应的beanName,很多同学可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/
   String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   /**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/
   Object sharedInstance = getSingleton(beanName);
   // 如果bean的单例对象找到了,且没有创建bean实例时要使用的参数
   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 + "'");
         }
      }
      // 返回对象的实例,很多同学会理解不了这句话存在的意义,当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      // 当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况,那么直接抛出异常
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      // 如果bean定义不存在,就检查父工厂是否有
      BeanFactory parentBeanFactory = getParentBeanFactory();
      // 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         // 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
         String nameToLookup = originalBeanName(name);
         // 如果父工厂是AbstractBeanFactory的实例
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            // 调用父工厂的doGetBean方法,就是该方法。【递归】
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            // Delegation to parent with explicit args.
            // 如果有创建bean实例时要使用的参数
            // Delegation to parent with explicit args. 使用显示参数委派给父工厂
            // 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else if (requiredType != null) {
            // No args -> delegate to standard getBean method.
            // 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
            // 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
         else {
            // 使用父工厂获取bean,通过bean全类名
            return (T) parentBeanFactory.getBean(nameToLookup);
         }
      }
      // 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录
      if (!typeCheckOnly) {
         // 为beanName标记为已经创建(或将要创建)
         markBeanAsCreated(beanName);
      }

      try {
         // 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,
         // 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性
         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         // 检查mbd的合法性,不合格会引发验证异常
         checkMergedBeanDefinition(mbd, beanName, args);

         // Guarantee initialization of beans that the current bean depends on.
         // 如果存在依赖的bean的话,那么则优先实例化依赖的bean
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            // 如果存在依赖,则需要递归实例化依赖的bean
            for (String dep : dependsOn) {
               // 如果beanName已注册依赖于dependentBeanName的关系
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               // 注册各个bean的依赖关系,方便进行销毁
               registerDependentBean(dep, beanName);
               try {
                  // 递归优先实例化被依赖的Bean
                  getBean(dep);
               }
               // 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // Create bean instance.
         // 创建bean的实例对象
         if (mbd.isSingleton()) {
            // 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  // 为给定的合并后BeanDefinition(和参数)创建一个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临时引用的任何Bean
                  // 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
                  destroySingleton(beanName);
                  // 重新抛出ex
                  throw ex;
               }
            });
            // 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
            // FactoryBean会直接返回beanInstance实例
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
         // 原型模式的bean对象创建
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            // 它是一个原型 -> 创建一个新实例
            // 定义prototype实例
            Object prototypeInstance = null;
            try {
               // 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中
               beforePrototypeCreation(beanName);
               // 为mbd(和参数)创建一个bean实例
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               // 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
               afterPrototypeCreation(beanName);
            }
            // 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
            // FactoryBean会直接返回beanInstance实例
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         else {
            // 指定的scope上实例化bean
            String scopeName = mbd.getScope();
            if (!StringUtils.hasLength(scopeName)) {
               throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
            }
            // 从scopes中获取scopeName对于的Scope对象
            Scope scope = this.scopes.get(scopeName);
            // 如果scope为null
            if (scope == null) {
               // 抛出非法状态异常:没有名为'scopeName'的scope注册
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               // 从scope中获取beanName对应的实例对象
               Object scopedInstance = scope.get(beanName, () -> {
                  // 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中
                  beforePrototypeCreation(beanName);
                  try {
                     // 为mbd(和参数)创建一个bean实例
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     // 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
                     afterPrototypeCreation(beanName);
                  }
               });
               // 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
               // FactoryBean会直接返回beanInstance实例
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
               // 捕捉非法状态异常
               // 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此
               // beanDefinition一个作用域代理
               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) {
         // 捕捉获取Bean对象抛出的Bean异常
         // 在Bean创建失败后,对缓存的元数据执行适当的清理
         cleanupAfterBeanCreationFailure(beanName);
         // 重新抛出ex
         throw ex;
      }
   }

   // Check if required type matches the type of the actual bean instance.
   // 检查requiredType是否与实际Bean实例的类型匹配
   // 如果requiredType不为null&&bean不是requiredType的实例
   if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
         // 获取此BeanFactory使用的类型转换器,将bean转换为requiredType
         T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
         // 如果convertedBean为null
         if (convertedBean == null) {
            // 抛出Bean不是必要类型的异常
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
         }
         // 返回convertedBean
         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());
      }
   }
   // 将bean返回出去
   return (T) bean;
}
getDependsOn

如果存在依赖的bean的话,那么则优先实例化依赖的bean;如:

<bean id="a" class="com.armin.self_editor.Customer" depends-on="b"/>
<bean id="b" class="com.armin.self_aware.MyAwareProcessor"/>

depends-on属性值为需要优先实例化的依赖bean

getSingleton

返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个对象

Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)

此处只有在getSingleton()中调用ObjectFactory对象的的getObject()方法时才会执行如下匿名内部内的业务逻辑createBean()

sharedInstance = getSingleton(beanName, () -> {
  try {
    // 为给定的合并后BeanDefinition(和参数)创建一个bean实例
    return createBean(beanName, mbd, args);
  }
  catch (BeansException ex) {
    // 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
    // 接收到该Bean临时引用的任何Bean
    // 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
    destroySingleton(beanName);
    // 重新抛出ex
    throw ex;
  }
});
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  // 如果beanName为null,抛出异常
  Assert.notNull(beanName, "Bean name must not be null");
  // 使用单例对象的高速缓存Map作为锁,保证线程同步
  synchronized (this.singletonObjects) {
    // 从单例对象的高速缓存Map中获取beanName对应的单例对象
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果单例对象获取不到
    if (singletonObject == null) {
      // 如果当前在destorySingletons中
      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 + "'");
      }
      // 创建单例之前的回调,默认实现将单例注册为当前正在创建中
      beforeSingletonCreation(beanName);
      // 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
      boolean newSingleton = false;
      // 有抑制异常记录标记,没有时为true,否则为false
      boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
      // 如果没有抑制异常记录
      if (recordSuppressedExceptions) {
        // 对抑制的异常列表进行实例化(LinkedHashSet)
        this.suppressedExceptions = new LinkedHashSet<>();
      }
      try {
        // 从单例工厂中获取对象
        singletonObject = singletonFactory.getObject();
        // 生成了新的单例对象的标记为true,表示生成了新的单例对象
        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.
        // 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态
        // 尝试从单例对象的高速缓存Map中获取beanName的单例对象
        singletonObject = this.singletonObjects.get(beanName);
        // 如果获取失败,抛出异常
        if (singletonObject == null) {
          throw ex;
        }
      }
      // 捕捉Bean创建异常
      catch (BeanCreationException ex) {
        // 如果没有抑制异常记录
        if (recordSuppressedExceptions) {
          // 遍历抑制的异常列表
          for (Exception suppressedException : this.suppressedExceptions) {
            // 将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
            ex.addRelatedCause(suppressedException);
          }
        }
        // 抛出异常
        throw ex;
      }
      finally {
        // 如果没有抑制异常记录
        if (recordSuppressedExceptions) {
          // 将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
          // 可防止异常信息的混乱
          this.suppressedExceptions = null;
        }
        // 创建单例后的回调,默认实现将单例标记为不在创建中
        afterSingletonCreation(beanName);
      }
      // 生成了新的单例对象
      if (newSingleton) {
        // 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
        addSingleton(beanName, singletonObject);
      }
    }
    // 返回该单例对象
    return singletonObject;
  }
}

remark

  • singletonObjects:一级缓存

  • beforeSingletonCreation:创建单例之前的回调

    protected void beforeSingletonCreation(String beanName) {
       // 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后,出现
       // beanName已经在当前正在创建的bean名称列表中添加过
       if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
          // 抛出当前正在创建的Bean异常
          throw new BeanCurrentlyInCreationException(beanName);
       }
    }
    
  • singletonFactory.getObject():实际的创建bean的方法指向的是上述匿名内部类中的createBean()

createBean
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
		// 锁定class,根据设置的class属性或者根据className来解析class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		// 进行条件筛选,重新赋值RootBeanDefinition,并设置BeanClass属性
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			// 重新创建一个RootBeanDefinition对象
			mbdToUse = new RootBeanDefinition(mbd);
			// 设置BeanClass属性值
			mbdToUse.setBeanClass(resolvedClass);
		}
		// 验证及准备覆盖的方法,lookup-method  replace-method,当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// 实际创建bean的调用
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

remark

  • resolveBeanClass:为指定的bean定义解析bean类,将bean类名解析为Class引用(如果需要),并将解析后的Class存储在bean定义中以备将来使用

    protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
      throws CannotLoadBeanClassException {
    
      try {
        // 判断mbd的定义信息中是否包含beanClass,并且是Class类型的,如果是直接返回,否则的话进行详细的解析
        if (mbd.hasBeanClass()) {
          // 如果mbd指定了bean类
          return mbd.getBeanClass();
        }
        // 判断是否有安全管理器(jdbc中的DriverManager中loadInitialDrivers一致,doPrivileged是一个本地方法)
        if (System.getSecurityManager() != null) {
          return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
                                               () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
        }
        else {
          // 进行详细的处理解析过程
          return doResolveBeanClass(mbd, typesToMatch);
        }
      }
      catch (PrivilegedActionException pae) {
        ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
      }
      catch (ClassNotFoundException ex) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
      }
      catch (LinkageError err) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
      }
    }
    
    • doResolveBeanClass:获取mbd配置的bean类名,将bean类名解析为Class对象,并将解析后的Class对象缓存在mdb中以备将来使用

      private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
            throws ClassNotFoundException {
      
         // 获取该工厂的加载bean用的类加载器
         ClassLoader beanClassLoader = getBeanClassLoader();
         // 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有
         // 临时类加载器器时,该动态类加载器就是该工厂的临时类加载器
         ClassLoader dynamicLoader = beanClassLoader;
         // 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要
         boolean freshResolve = false;
      
         //如果有传入要匹配的类型
         if (!ObjectUtils.isEmpty(typesToMatch)) {
            // 仅进行类型检查时(即尚未创建实际实例),请使用指定的临时类加载器
            // 获取该工厂的临时类加载器,该临时类加载器专门用于类型匹配
            ClassLoader tempClassLoader = getTempClassLoader();
            // 如果成功获取到临时类加载器
            if (tempClassLoader != null) {
               // 以该工厂的临时类加载器作为动态类加载器
               dynamicLoader = tempClassLoader;
               // 标记mdb的配置的bean类名需要重新被dynameicLoader加载
               freshResolve = true;
               // DecoratingClassLoader:装饰ClassLoader的基类,提供对排除的包和类的通用处理
               // 如果临时类加载器是DecoratingClassLoader的基类
               if (tempClassLoader instanceof DecoratingClassLoader) {
                  // 将临时类加载器强转为DecoratingClassLoader实例
                  DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                  // 对要匹配的类型进行在装饰类加载器中的排除,以交由父ClassLoader以常规方式处理
                  for (Class<?> typeToMatch : typesToMatch) {
                     dcl.excludeClass(typeToMatch.getName());
                  }
               }
            }
         }
      
         // 从mbd中获取配置的bean类名
         String className = mbd.getBeanClassName();
         // 如果能成功获得配置的bean类名
         if (className != null) {
            //评估benaDefinition中包含的className,如果className是可解析表达式,会对其进行解析,否则直接返回className:
            Object evaluated = evaluateBeanDefinitionString(className, mbd);
            // 判断className是否等于计算出的表达式的结果,如果不等于,那么判断evaluated的类型
            if (!className.equals(evaluated)) {
               // A dynamically resolved expression, supported as of 4.2...
               // 如果evaluated属于Class实例
               if (evaluated instanceof Class) {
                  // 强转evaluatedw为Class对象并返回出去
                  return (Class<?>) evaluated;
               }
               // 如果evaluated属于String实例
               else if (evaluated instanceof String) {
                  // 将evaluated作为className的值
                  className = (String) evaluated;
                  // 标记mdb的配置的bean类名需要重新被dynameicLoader加载
                  freshResolve = true;
               }
               else {
                  // 抛出非法状态异常:无效的类名表达式结果:evaluated
                  throw new IllegalStateException("Invalid class name expression result: " + evaluated);
               }
            }
            // 如果mdb的配置的bean类名需要重新被dynameicLoader加载
            if (freshResolve) {
               // 当使用临时类加载器进行解析时,请尽早退出以避免将已解析的类存储在BeanDefinition中
               // 如果动态类加载器不为null
               if (dynamicLoader != null) {
                  try {
                     // 使用dynamicLoader加载className对应的类型,并返回加载成功的Class对象
                     return dynamicLoader.loadClass(className);
                  }
                  // 捕捉未找到类异常,
                  catch (ClassNotFoundException ex) {
                     if (logger.isTraceEnabled()) {
                        logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                     }
                  }
               }
               // 使用classLoader加载name对应的Class对象,该方式是Spring用于代替Class.forName()的方法,支持返回原始的类实例(如'int')
               // 和数组类名 (如'String[]')。此外,它还能够以Java source样式解析内部类名(如:'java.lang.Thread.State'
               // 而不是'java.lang.Thread$State')
               return ClassUtils.forName(className, dynamicLoader);
            }
         }
      
         // 定期解析,将结果缓存在BeanDefinition中...
         // 使用classLoader加载当前BeanDefinitiond对象所配置的Bean类名的Class对象(每次调用都会重新加载,可通过
         // AbstractBeanDefinition#getBeanClass 获取缓存)
         return mbd.resolveBeanClass(beanClassLoader);
      }
      
      • resolveBeanClass

        public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
           // 获取className
           String className = getBeanClassName();
           if (className == null) {
              return null;
           }
           // 获取当前bean对应的Class对象
           Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
           this.beanClass = resolvedClass;
           return resolvedClass;
        }
        
        • ClassUtils.forName:使用classLoader加载name对应的Class对象

          public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
                throws ClassNotFoundException, LinkageError {
          
             // 如果name为null,抛出异常
             Assert.notNull(name, "Name must not be null");
          
             // 如果name是个原始类型名,就获取其对应的Class
             Class<?> clazz = resolvePrimitiveClassName(name);
             // 如果clazz为null
             if (clazz == null) {
                // 从缓存Map中获取name对应的Class
                clazz = commonClassCache.get(name);
             }
             // 如果clazz不为null
             if (clazz != null) {
                // 直接返回clazz
                return clazz;
             }
          
             // "java.lang.String[]" style arrays
             // "java.lang.String[]" style arrays 'java.lang.String[]'样式数组,表示原始数组类名
             // 如果name是以'[]'结尾的
             if (name.endsWith(ARRAY_SUFFIX)) {
                // 截取出name'[]'前面的字符串赋值给elementClassName
                String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
                // 传入elementClassName递归本方法获取其Class
                Class<?> elementClass = forName(elementClassName, classLoader);
                // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去
                return Array.newInstance(elementClass, 0).getClass();
             }
          
             // "[Ljava.lang.String;" style arrays
             // 如果names是以'[L'开头且以';'结尾
             if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
                // 截取出name'[L'到';'之间的字符串赋值给elementName
                String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
                // 传入elementName递归本方法获取其Class
                Class<?> elementClass = forName(elementName, classLoader);
                // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去
                return Array.newInstance(elementClass, 0).getClass();
             }
          
             // "[[I" or "[[Ljava.lang.String;" style arrays
             // "[[I" or "[[Ljava.lang.String;" style arrays '[[I' 或者 '[[Ljava.lang.String;'样式数组,表示内部数组类名
             if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
                // 截取出name '['后面的字符串赋值给elementName
                String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
                // 传入elementName递归本方法获取其Class
                Class<?> elementClass = forName(elementName, classLoader);
                // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去
                return Array.newInstance(elementClass, 0).getClass();
             }
          
             // 将classLoader赋值给clToUse变量
             ClassLoader clToUse = classLoader;
             // 如果clToUse为null
             if (clToUse == null) {
                // 获取默认类加载器,一般返回线程上下文类加载器,没有就返回加载ClassUtils的类加载器,
                // 还是没有就返回系统类加载器,最后还是没有就返回null
                clToUse = getDefaultClassLoader();
             }
             try {
                // 返回与给定的字符串名称相关联类或接口的Class对象。
                return Class.forName(name, false, clToUse);
             }
             catch (ClassNotFoundException ex) {
                // 如果找到不到类时
                // 获取最后一个包名分割符'.'的索引位置
                int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
                // 如果找到索引位置
                if (lastDotIndex != -1) {
                   // 尝试将name转换成内部类名,innerClassName=name的包名+'$'+name的类名
                   String innerClassName =
                         name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
                   try {
                      // 通过clToUse获取innerClassName对应的Class对象
                      return Class.forName(innerClassName, false, clToUse);
                   }
                   catch (ClassNotFoundException ex2) {
                      // Swallow - let original exception get through
                   }
                }
                // 当将name转换成内部类名仍然获取不到Class对象时,抛出异常
                throw ex;
             }
          }
          
  • lookup-method:解决了单利引用了原型模式(每次获取新的对象)

    Spring中默认的对象都是单例的,Spring会在一级缓存中持有该对象,方便下次直接获取。那么如果是原型作用域(scope="prototype")的话,会创建一个新的对象。如果想在一个单例模式的bean下引用一个原型模式的bean怎么办?

    在此时就需要引用lookup-method标签来解决此问题

    通过拦截器的方式每次需要的时候都去创建最新的对象,而不会把原型对象缓存起来

  • replaced-method:任意方法替换

    • OriginalDog:将要被替换的方法(此处方法重载)

      public class OriginalDog {
          public void sayHello() {
              System.out.println("Hello,I am a black dog...");
          }
      
          public void sayHello(String name) {
              System.out.println("Hello,I am a black dog, my name is " + name);
          }
      }
      
    • ReplaceDog

      import org.springframework.beans.factory.support.MethodReplacer;
      
      import java.lang.reflect.Method;
      import java.util.Arrays;
      
      public class ReplaceDog implements MethodReplacer {
          @Override
          public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
              System.out.println("real execute method");
              Arrays.stream(args).forEach(System.out::print);
              return obj;
          }
      }
      
    • armin-self-method-overrides.xml

      <bean id="originalDog" class="com.armin.method_overrides.replace.OriginalDog">
          <replaced-method name="sayHello" replacer="replaceDog">
              <arg-type match="Str"/>
          </replaced-method>
      </bean>
      <bean id="replaceDog" class="com.armin.method_overrides.replace.ReplaceDog"/>
      

      <arg-type match="Str"/>有多种写法,如:match=java.lang.StringString或``Str`

      在元素中使用一个或多个<arg-type/>元素<replaced-method/> 来指示被覆盖的方法的方法签名。只有当方法被重载并且类中存在多个变体时,参数的签名才是必需的。为方便起见,参数的类型字符串可以是完全限定类型名称的子字符串。

    • Test

      import com.armin.method_overrides.replace.OriginalDog;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class Test {
      
          public static void main(String[] args) throws Throwable {
              ApplicationContext context = new ClassPathXmlApplicationContext("armin-self-method-overrides.xml");
              OriginalDog originalDog = (OriginalDog) context.getBean("originalDog");
              originalDog.sayHello("Three-baby");
          }
      }
      
    • Console

      real execute method
      Three-baby
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值