写点什么

Spring 系列之 IOC 容器初始化八

作者:王威07325
  • 2023-05-29
    上海
  • 本文字数:16372 字

    阅读完需:约 54 分钟

refresh 方法中的 finishBeanFactoryInitialization 方法

一星期一更的 springIOC 容器博文还是如期而至,随着 Spring 系列的不断更新,不知不觉已经三个月了,IOC 容器初始化理解博文已经快到结尾的阶段。写 SpringIOC 容器系列的文章的初衷是为了加深自己对 SpringIOC 的理解同时也是对 SpringIOC 容器内容的笔记,但随着自己文章的更新,我发现自己已经慢慢地爱上了写博文!!!


意气风发的时候更需要注意“谦卑”


finishBeanFactoryInitialization 方法

实例化所有剩余的(非惰性初始化)单例。


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. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(new StringValueResolver() { @Override public String resolveStringValue(String strVal) { return getEnvironment().resolvePlaceholders(strVal); } }); }
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 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. beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
复制代码


咱们分部分地慢慢讲解:

ConversionService

用于类型转换的服务接口。这是转换系统的入口点。调用 convert(Object, Class)以使用此系统执行线程安全的类型转换


其实就是 spring 给我们提供的类型转换功能的组件,转换器是什么?其实在 springmvc 中是会有使用的:


@RequestMapping("/quickCreateReceivableOrder")    @ResponseBody    public Object quickCreateReceivableOrder(String ids) throws SessionException {        Staff staff = getStaff();        return saleTradeBusiness.quickCreateReceivableOrder(staff,Arrays.asList(ArrayUtils.toLongArray(ids,",")));    }
复制代码


为什么 String 能够接受前端传过来的数据,就是因为有转换器的存在。


Spring 内置的 converter 是怎么注册的?


DefaultConversionService 的实例化的时候就会将一些常用的 converter 注册进去,具体有哪些 converter 大家可以自己去看看。


public DefaultConversionService() {    addDefaultConverters(this);  }
public static void addDefaultConverters(ConverterRegistry converterRegistry) { addScalarConverters(converterRegistry); addCollectionConverters(converterRegistry);
converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry)); if (jsr310Available) { Jsr310ConverterRegistrar.registerJsr310Converters(converterRegistry); }
converterRegistry.addConverter(new ObjectToObjectConverter()); converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry)); converterRegistry.addConverter(new FallbackObjectToStringConverter()); if (javaUtilOptionalClassAvailable) { converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry)); } }
复制代码
StringValueResolver

解析给定的字符串值,例如解析占位符、SpEL 计算


这个接口就只有一个方法,用于解析占位符和 SpEL 计算


public interface StringValueResolver {
/** * Resolve the given String value, for example parsing placeholders. * @param strVal the original String value (never {@code null}) * @return the resolved String value (may be {@code null} when resolved to a null * value), possibly the original String value itself (in case of no placeholders * to resolve or when ignoring unresolvable placeholders) * @throws IllegalArgumentException in case of an unresolvable String value */ String resolveStringValue(String strVal);
}
复制代码


看一下 spring 中是怎么去解析的:


if (!beanFactory.hasEmbeddedValueResolver()) {      beanFactory.addEmbeddedValueResolver(new StringValueResolver() {        @Override        public String resolveStringValue(String strVal) {          return getEnvironment().resolvePlaceholders(strVal);        }      });    }
复制代码


最终调用的是 PropertyPlaceholderHelper#parseStringValue 方法去进行一个解析的:


protected String parseStringValue(      String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
StringBuilder result = new StringBuilder(value);
int startIndex = value.indexOf(this.placeholderPrefix); while (startIndex != -1) { int endIndex = findPlaceholderEndIndex(result, startIndex); if (endIndex != -1) { String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(originalPlaceholder)) { throw new IllegalArgumentException( "Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); } // Recursive invocation, parsing placeholders contained in the placeholder key. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // Now obtain the value for the fully resolved key... String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { propVal = defaultValue; } } } if (propVal != null) { // Recursive invocation, parsing placeholders contained in the // previously resolved placeholder value. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { // Proceed with unprocessed value. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'" + " in value \"" + value + "\""); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } }
return result.toString(); }
复制代码


placeholderPrefix – 表示占位符开始的前缀 placeholderSuffix – 表示占位符结束的后缀 valueSeparator – 占位符变量和相关默认值之间的分隔符(如果有)

LoadTimeWeaverAware

尽早初始化 LoadTimeWeaverAware bean 以允许尽早注册其转换器


实现了此接口的 bean 可以得到 LoadTimeWeaver,此处仅仅初始化。


String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);    for (String weaverAwareName : weaverAwareNames) {      getBean(weaverAwareName);    }
复制代码


InstantiateSingletons


确保实例化所有非惰性初始化单例,同时考虑 FactoryBeans


首先进行 Singleton 的初始化,其中如果 bean 是 FactoryBean 类型(注意,只定义了 factory-method 属性的普通 bean 并不是 FactoryBean),并且还是 SmartFactoryBean 类型,那么需要判断是否需要 eagerInit(isEagerInit 是此接口定义的方法)


public void preInstantiateSingletons() throws BeansException {    if (this.logger.isDebugEnabled()) {      this.logger.debug("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. List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { return ((SmartFactoryBean<?>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } }
// Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
复制代码


这个方法比较重要,我们分部分去讲解:


  1. 获取 beanfactory 中所有的 beanName

  2. 触发所有非惰性单例 bean 的初始化

  3. 为所有适用的 bean 触发初始化后回调


获取 beanfactory 中所有的 beanName


这里比较简单,就是将 beanfactory 中的 beanDefinitionNames 放入一个新的 List 集合中。beanDefinitionNames 本身就是一个 List 集合,为什么要在这里重新进行一个赋值,是因为如果 beanDefinitionNames 是一个 null 值,那么这里会报异常,不会进行下面的步骤。


List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
复制代码


触发所有非惰性单例 bean 的初始化


for (String beanName : beanNames) {      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {        if (isFactoryBean(beanName)) {          final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);          boolean isEagerInit;          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {              @Override              public Boolean run() {                return ((SmartFactoryBean<?>) factory).isEagerInit();              }            }, getAccessControlContext());          }          else {            isEagerInit = (factory instanceof SmartFactoryBean &&                ((SmartFactoryBean<?>) factory).isEagerInit());          }          if (isEagerInit) {            getBean(beanName);          }        }        else {          getBean(beanName);        }      }    }
复制代码


getMergedLocalBeanDefinition:


如果给定 bean 的定义是子 bean 定义,则通过与父合并返回给定 bean 的 RootBeanDefinition


最终调用的 getMergedBeanDefinition(String beanName, BeanDefinition bd, BeanDefinition containingBd)


参数:beanName – bean 定义的名称 bd – 原始 bean 定义 (Root/ChildBeanDefinition)containsBd – 如果是内部 bean,则包含 bean 定义,如果是顶级 bean, null


protected RootBeanDefinition getMergedBeanDefinition(      String beanName, BeanDefinition bd, BeanDefinition containingBd)      throws BeanDefinitionStoreException {        ..............        ...............        ..............        if (!StringUtils.hasLength(mbd.getScope())) {          mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);        }
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); }
if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } }
return mbd; } }
复制代码


就是对相应的 beanDefinition 进行对父 beanDifinition 进行一个合并。


在对 bean 进行实例化之前,会进行相应的判断,:


!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
复制代码


如果 bean 不能是抽象类、作用域是 Singleton、不是懒加载。再对是否是 factorybean 进行一个判断,然后开始 bean 的初始化。


getBean


这个方法最终会调用 AbstractBeanFactory#doGetBean 方法:


protected <T> T doGetBean(      final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)      throws BeansException {    //返回 bean 名称,必要时去除工厂取消引用前缀,并将别名解析为规范名称    final String beanName = transformedBeanName(name);    Object bean;
// 返回在给定名称下注册的(原始)单例对象。//检查已经实例化的单例,还允许对当前创建的单例进行早期引用(解决循环引用) Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } //获取给定 bean 实例的对象,bean 实例本身或其创建的对象(如果是 FactoryBean) bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
else { //判断是否存在循环引用,如果有,则抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
// 检查此工厂中是否存在 bean 定义,这里也包括对父工厂的检查 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 如果工厂本身里面没有,则开始检查父工厂的里面是否有没有 String nameToLookup = originalBeanName(name); if (args != null) { // 带参数的去获取bean return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // 不带参数的去获取bean return parentBeanFactory.getBean(nameToLookup, requiredType); } } //bean类型检查 if (!typeCheckOnly) { //将指定的 bean 标记为已创建(或即将创建) markBeanAsCreated(beanName); }
try { //返回一个合并的 RootBeanDefinition,如果指定的 bean 对应于子 bean 定义,则遍历父 bean 定义 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //检查给定的合并 bean 定义,可能会引发验证异常 checkMergedBeanDefinition(mbd, beanName, args);
// 保证当前bean依赖的bean的初始化 //我们可以在spring中使用@dependsOn注解进行依赖设置或者通过xml文件中bean中的depends-on属性去设置 String[] dependsOn = mbd.getDependsOn(); //初始化依赖的对象 if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //为给定的 bean 注册一个依赖 bean,在给定的 bean 被销毁之前被销毁 registerDependentBean(dep, beanName); try { //bean的实例化 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } }
// 创建 bean 实例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { //为给定的合并 bean 定义(和参数)创建一个 bean 实例。 //如果是子定义,bean 定义将已经与父定义合并。 //所有 bean 检索方法都委托给此方法以进行实际的 bean 创建 return createBean(beanName, mbd, args); } catch (BeansException ex) { //销毁bean,如果bean实现了DisposableBean接口,则会在销毁的时候执行destroy方法 destroySingleton(beanName); throw ex; } } }); //获取给定 bean 实例的对象,bean 实例本身或其创建的对象(如果是 FactoryBean) bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //判断bean的scope是否是Prototype,如果是则进行原型类型的逻辑。 else if (mbd.isPrototype()) { Object prototypeInstance = null; try { //创建原型之前的回调。默认实现将原型注册为当前正在创建中 beforePrototypeCreation(beanName); //创建bean prototypeInstance = createBean(beanName, mbd, args); } finally { //创建原型后的回调。默认实现将原型标记为不再处于创建状态,与beforePrototypeCreation对应 afterPrototypeCreation(beanName); } //获取给定 bean 实例的对象,bean 实例本身或其创建的对象(如果是 FactoryBean) bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //如果不是上面两种scope,先从beandefinition中拿scope,然后进行相应的实例化操作 //其他的操作和上面的bean实例化一样 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { 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) { cleanupAfterBeanCreationFailure(beanName); throw ex; } }
// 检查所需类型是否与实际 bean 实例的类型匹配 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { try { //将值转换为所需的类型(如果需要,从字符串)。 //从 String 到任何类型的转换通常会使用 PropertyEditor 类的setAsText方法,或 ConversionService 中的 Spring Converter //如果类型不匹配会抛出TypeMismatchException return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
复制代码


代码图形流程:



AbstractAutowireCapableBeanFactory#createBean


protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {    if (logger.isDebugEnabled()) {      logger.debug("Creating instance of bean '" + beanName + "'");    }    RootBeanDefinition mbdToUse = mbd;
// 确保此时实际解析了 bean 类,并克隆 bean 定义以防动态解析的 Class 无法存储在共享合并 bean 定义中 //为指定的 bean 定义解析 bean 类,将 bean 类名称解析为 Class 引用(如果需要)并将解析的 Class 存储在 bean 定义中以供进一步使用 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); }
// 进行方法重写的逻辑 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); }
try { // 应用实例化前后处理器,解析指定 bean 是否存在实例化前快捷方式 // 主要就是对实现了InstantiationAwareBeanPostProcessor接口的回调,这个接口是spring的内置接口。 //建议尽可能实现普通的BeanPostProcessor接口,或者从InstantiationAwareBeanPostProcessorAdapter派生,以屏蔽对该接口的扩展 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); } //调用doCreateBean,完成spring对bean的初始化 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
复制代码


代码图形流程:



AbstractAutowireCapableBeanFactory#doCreateBean


真是执行 bean 的创建的方法


protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)      throws BeanCreationException {
// 这里定义一个Bean的包装类,这么设计是因为用一种类型表示所有的Bean,达到统一对象的处理,这种设计思想在tomcat中的Servlet的创建也有所体现 BeanWrapper instanceWrapper = null; //如果bean的scope是Singleton则从spring的缓存中拿 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //如果缓存中没有此beanwrapper,则创建一个新的beanwrapper对象通过相应的策略:工厂方法、构造函数自动装配、简单的实例化 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } //获取bean对象 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //获取bean的类型 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); //将对象类型赋值给beandefinition mbd.resolvedTargetType = beanType;
// 允许后处理器修改合并的 bean 定义 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //如果bean实现了MergedBeanDefinitionPostProcessor接口,则在这里执行回调 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } }
// 急切地缓存单例以便能够解析循环引用,即使是由生命周期接口(如 BeanFactoryAware)触发 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); }
// 初始化bean对象 Object exposedObject = bean; try { //使用 bean 定义中的属性值填充给定 BeanWrapper 中的 bean 实例 //在这里如果bean实现了InstantiationAwareBeanPostProcessor接口, 那么会在这里执行相应的逻辑。 //也就是说,实现了InstantiationAwareBeanPostProcessor接口的会在实例化后但在设置显式属性或发生自动装配之前进行方法的回调 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //初始化给定的 bean 实例,应用工厂回调以及 init 方法和 bean 后处理器。 //从createBean调用传统定义的 bean,从initializeBean调用现有 bean 实例。 exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } //暴露早期的单例对象 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } }
// 将给定的 bean 添加到此工厂中的一次性 bean 列表中,注册其 DisposableBean 接口和/或在工厂关闭时调用的给定销毁方法(如果适用)。 //仅适用于单例。 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); }
return exposedObject; }
复制代码


代码图形流程:



AbstractAutowireCapableBeanFactory#populateBean


为 bean 对象属性赋值


protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {    //返回此 bean 的属性值(从不为null )    PropertyValues pvs = mbd.getPropertyValues();    //判断bean是否是空实例。    if (bw == null) {      if (!pvs.isEmpty()) {        throw new BeanCreationException(            mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");      }      else {        // 跳过空实例的属性填充阶段。        return;      }    }
// 让任何 InstantiationAwareBeanPostProcessors 有机会在设置属性之前修改 bean 的状态。例如,这可以用于支持字段注入的样式 boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } }
if (!continueWithPropertyPopulation) { return; }
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 如果适用,按名称添加基于自动装配的属性值 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); }
// 如果适用,根据类型添加基于自动装配的属性值。 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); }
pvs = newPvs; }
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } }
applyPropertyValues(beanName, mbd, bw, pvs); }
复制代码


代码图形流程:



AbstractAutowireCapableBeanFactory#initializeBean


初始化 bean 对象


protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {//不管有没有开启安全管理器都会检查Aware相关接口并设置相关依赖://BeanNameAware、BeanClassLoaderAware、BeanFactoryAware    if (System.getSecurityManager() != null) {      AccessController.doPrivileged(new PrivilegedAction<Object>() {        @Override        public Object run() {          invokeAwareMethods(beanName, bean);          return null;        }      }, getAccessControlContext());    }    else {      invokeAwareMethods(beanName, bean);    }
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //这个方法非常的熟悉,如果bean实现了BeanPostProcessor接口,则进行postProcessBeforeInitialization方法的回调 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
try { ///检查 bean 是否实现了 InitializingBean 或定义了自定义的 init 方法,如果是,则调用必要的回调。 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //跟上面的wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);对应 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
复制代码


代码图形流程:



本篇文章内容理解比较起来比较难,同时篇幅比较大,采用了图文结合的方式去完成,图是借鉴了几张图了解spring doGetBean一文。这篇可以说是 springIOC 容器初始化和实例化过程中最重要的过程,所以希望各位能够自己去源码跟随博主的思路去走一遍,这样能够加深自己对 springIOC 容器初始化的理解,最后希望各位看完的小伙伴点点赞!!!

发布于: 25 分钟前阅读数: 2
用户头像

王威07325

关注

还未添加个人签名 2021-12-29 加入

还未添加个人简介

评论

发布
暂无评论
Spring系列之IOC容器初始化八_spring ioc_王威07325_InfoQ写作社区