详解Spring中Bean的加载的方法

之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,从之前的例子开始.

Spring中加载一个bean的方式:

TestBean bean = factory.getBean("testBean");

来看看getBean(String name)方法源码,

@Override
public Object getBean(String name) throws BeansException {
  return doGetBean(name, null, null, false);
}

该getBean(String name)方法位于AbstractBeanFactory抽象类中,AbstractBeanFactory与XmlBeanFactory类关系可以看下图:

接下去跟进doGetBean()方法源码:

protected <T> T doGetBean(
    final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
    throws BeansException {
  // 提取beanName
  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 + "'");
      }
    }
    // 返回实例,有时存在如BeanFactory这样情况时并不是直接返回实例本身而是返回指定方法返回的实例
    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.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    // 如果在所有已经加载的类中没有beanName则会尝试从parentBeanFactory中检测
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
      // Not found -> check parent.
      String nameToLookup = originalBeanName(name);
      // 到BeanFactory查找
      if (args != null) {
        // Delegation to parent with explicit args.
        return (T) parentBeanFactory.getBean(nameToLookup, args);
      }
      else {
        // No args -> delegate to standard getBean method.
        return parentBeanFactory.getBean(nameToLookup, requiredType);
      }
    }
    // 如果不是只做类型检查则是创建bean
    if (!typeCheckOnly) {
      markBeanAsCreated(beanName);
    }

    try {
      // 将存储XML配置文件的GernericBeanDefinition转换成RootBeanDefinition,如果BeanName是子Bean的话会合并父类的相关属性
      final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      checkMergedBeanDefinition(mbd, beanName, args);

      // Guarantee initialization of beans that the current bean depends on.
      String[] dependsOn = mbd.getDependsOn();
      // 如果存在依赖的话要递归实例化依赖的bean
      if (dependsOn != null) {
        for (String dependsOnBean : dependsOn) {
          if (isDependent(beanName, dependsOnBean)) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
          }
          registerDependentBean(dependsOnBean, beanName);
          getBean(dependsOnBean);
        }
      }

      // Create bean instance.
      // 依赖的bean实例化完后就可以实例化mbd了
      if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
          @Override
          public Object getObject() throws BeansException {
            try {
              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.
              destroySingleton(beanName);
              throw ex;
            }
          }
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
      }

      else if (mbd.isPrototype()) {
        // It's a prototype -> create a new instance.
        Object prototypeInstance = null;
        try {
          beforePrototypeCreation(beanName);
          prototypeInstance = createBean(beanName, mbd, args);
        }
        finally {
          afterPrototypeCreation(beanName);
        }
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
      }

      else {
        // 在对应的scope上实例化bean
        String scopeName = mbd.getScope();
        final Scope scope = this.scopes.get(scopeName);
        if (scope == null) {
          throw new IllegalStateException("No Scope registered for scope '" + 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.isAssignableFrom(bean.getClass())) {
    try {
      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;
}

整个bean加载的过程步骤相对繁琐,主要步骤有以下几点:

1、转换beanName

要知道平时开发中传入的参数name可能只是别名,也可能是FactoryBean,所以需要进行解析转换,一般会进行以下解析:

(1)消除修饰符,比如name="&test",会去除&使name="test";

(2)取alias表示的最后的beanName,比如别名test01指向名称为test02的bean则返回test02。

2、从缓存中加载实例

实例在Spring的同一个容器中只会被创建一次,后面再想获取该bean时,就会尝试从缓存中获取;如果获取不到的话再从singletonFactories中加载。

3、实例化bean

缓存中记录的bean一般只是最原始的bean状态,这时就需要对bean进行实例化。如果得到的是bean的原始状态,但又要对bean进行处理,这时真正需要的是工厂bean中定义的factory-method方法中返回的bean,上面源码中的getObjectForBeanInstance就是来完成这个工作的。

4、检测parentBeanFacotory

从源码可以看出如果缓存中没有数据会转到父类工厂去加载,源码中的!containsBeanDefinition(beanName)就是检测如果当前加载的xml配置文件中不包含beanName所对应的配置,就只能到parentBeanFacotory去尝试加载bean。

5、存储XML配置文件的GernericBeanDefinition转换成RootBeanDefinition之前的文章介绍过XML配置文件中读取到的bean信息是存储在GernericBeanDefinition中的,但Bean的后续处理是针对于RootBeanDefinition的,所以需要转换后才能进行后续操作。

6、初始化依赖的bean

这里应该比较好理解,就是bean中可能依赖了其他bean属性,在初始化bean之前会先初始化这个bean所依赖的bean属性。

7、创建bean

Spring容器根据不同scope创建bean实例。

整个流程就是如此,下面会讲解一些重要步骤的源码。

上面有提到,单例在Spring中的同一容器中只会被创建一次,后面再获取bean的话会直接从缓存中获取,这里是尝试加载,先从缓存中加载,再次就是从singletonFactories中加载;因为在bean中可能会在依赖注入,要避免循环依赖,Spring创建bean时会不等bean创建完成就会将创建该bean的ObjectFactory提前曝光加入到缓存中,但下一个bean创建时要依赖上个bean的话,就直接使用ObjectFacotry。

@Override
public Object getSingleton(String beanName) {
  return getSingleton(beanName, true); // true表示允许早期依赖
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  // 尝试从缓存获取实例
  Object singletonObject = this.singletonObjects.get(beanName);
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
      // 若该bean正在加载则不处理
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
        if (singletonFactory != null) {
          singletonObject = singletonFactory.getObject();
          // 存入到缓存中
          this.earlySingletonObjects.put(beanName, singletonObject);
          this.singletonFactories.remove(beanName);
        }
      }
    }
  }
  return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
/* 这两个方法在DefaultSingletonBeanRegistry类中 */

从源码可以看出这个方法先尝试从singletonObjects中获取实例,如果获取不到值就从earlySingletonObject中去获取,如果再获取不到的话则到singletonFactories里获取beanName对应的ObjectFactory,再调用这个ObjectFactory的getObject来创建bean,并放到earlySingletonObject中,并且从singletonFactories里remove掉这个ObjectFactory。这里有几个存储bean的不同map:

  1. -singletonObjects:保存BeanName和创建bean实例之间的关系。
  2. -singletonFactories:保存BeanName和创建bean实例的工厂之间的关系。
  3. -earlySingletonObject:保存BeanName和创建bean实例之间的关系,与-singletonObjects不同的是当一个单例bean被放到里面后,那当bean在创建过程中,就可以通过getBean方法获取到,可以用来检测循环引用。
  4. -registeredSingletons:保存当前所有已注册的bean。

如果上面缓存中不存在已经加载的单例bean就要重新开始bean的加载过程了,Spring中使用getSingleton重载方法实现bean的加载过程。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "'beanName' must not be null");
  synchronized (this.singletonObjects) {
    // 先检查bean是否已经加载
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果空才进行singleton的bean的初始化
    if (singletonObject == null) {
      if (this.singletonsCurrentlyInDestruction) {
        throw new BeanCreationNotAllowedException(beanName,
            "Singleton bean creation not allowed while the 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);
      boolean newSingleton = false;
      boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
      if (recordSuppressedExceptions) {
        this.suppressedExceptions = new LinkedHashSet<Exception>();
      }
      try {
        // 初始化bean
        singletonObject = singletonFactory.getObject();
        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.
        singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
          throw ex;
        }
      }
      catch (BeanCreationException ex) {
        if (recordSuppressedExceptions) {
          for (Exception suppressedException : this.suppressedExceptions) {
            ex.addRelatedCause(suppressedException);
          }
        }
        throw ex;
      }
      finally {
        if (recordSuppressedExceptions) {
          this.suppressedExceptions = null;
        }
        afterSingletonCreation(beanName);
      }
      if (newSingleton) {
        // 存入缓存
        addSingleton(beanName, singletonObject);
      }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
  }
}

这段代码使用了回调方法,使程序可以在单例创建的前后做一些准备及处理操作,真正的获取单例bean的方法其实并不是在这个方法实现的,而是在ObjectFactory类型的实例singletonFactory中实现的。

下面准备创建bean

看看createBean()方法源码(该方法在AbstractAutowireCapableBeanFactory类中):

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

  if (logger.isDebugEnabled()) {
    logger.debug("Creating instance of bean '" + beanName + "'");
  }
  // 锁定class,根据设置的class属性或根据className来解析Class
  resolveBeanClass(mbd, beanName);

  // 验证和准备覆盖的方法
  try {
    mbd.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
        beanName, "Validation of method overrides failed", ex);
  }

  try {
    // 用BeanPostProcessors返回代理来替代真正的实例
    Object bean = resolveBeforeInstantiation(beanName, mbd);
    if (bean != null) {
      return bean;
    }
  }
  catch (Throwable ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
        "BeanPostProcessor before instantiation of bean failed", ex);
  }

  Object beanInstance = doCreateBean(beanName, mbd, args);
  if (logger.isDebugEnabled()) {
    logger.debug("Finished creating instance of bean '" + beanName + "'");
  }
  return beanInstance;
}

从createBean()方法源码可以看出主要做了以下操作:

  1. 根据设置的class属性或根据className来解析Class;
  2. 对覆盖进行标记并验证,在Spring配置中是存在lookup-mothod和replace-method的,这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这个方法的操作也就是针对于这两个配置的;
  3. 应用初始化前的后处理器,最后创建bean。

在createBean()方法里执行完resolveBeforeInstantiation方法后,如果创建了代理且不为空的话就直接返回,否则需要进行常规bean的创建,这个创建过程是在doCreateBean中完成的,跟进源码:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
    // 根据指定bean使用相应策略创建实例
    instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
  Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

  // Allow post-processors to modify the merged bean definition.
  synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      mbd.postProcessed = true;
    }
  }

  // 检测循环依赖,是否需要提早曝光
  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");
    }
    // 避免循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
    addSingletonFactory(beanName, new ObjectFactory<Object>() {
      @Override
      public Object getObject() throws BeansException {
        // 对bean再次依赖引用
        // AOP也是在这里将advice动态织入bean中,若没有则直接返回bean,不做处理
        return getEarlyBeanReference(beanName, mbd, bean);
      }
    });
  }

  // Initialize the bean instance.
  Object exposedObject = bean;
  try {
    // 填充bean,注入属性值,如果存在依赖于其他bean的属性,会递归初始化
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
      // 调用初始化方法
      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);
    // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
    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.");
        }
      }
    }
  }

  // Register bean as disposable.
  try {
    // 依据scopse注册bean
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
}

上面源码完成的操作可以概括为以下几点:

  1. 开始是单例的话要先清除缓存;
  2. 实例化bean,将BeanDefinition转换为BeanWrapper;
  3. 使用MergedBeanDefinitionPostProcessor,Autowired注解就是通过此方法实现类型的预解析;
  4. 解决循环依赖问题;
  5. 填充属性,将属性填充到bean实例中;
  6. 注册DisposableBean;
  7. 创建完成并返回

接下来创建bean实例,看createBeanInstance()方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
  // 解析class
  Class<?> beanClass = resolveBeanClass(mbd, beanName);

  if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  }

  // 若工厂方法不为空则使用工厂方法初始化
  if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
  }

  // Shortcut when re-creating the same bean...
  boolean resolved = false;
  boolean autowireNecessary = false;
  if (args == null) {
    synchronized (mbd.constructorArgumentLock) {
      if (mbd.resolvedConstructorOrFactoryMethod != null) {
        resolved = true;
        autowireNecessary = mbd.constructorArgumentsResolved;
      }
    }
  }
  // 如果已经解析过则使用解析好的构造方法不需要再次锁定
  if (resolved) {
    if (autowireNecessary) {
      // 构造方法自动注入
      return autowireConstructor(beanName, mbd, null, null);
    }
    else {
      // 使用默认构造方法
      return instantiateBean(beanName, mbd);
    }
  }

  // 根据参数解析构造方法
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null ||
      mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    return autowireConstructor(beanName, mbd, ctors, args);
  }

  // No special handling: simply use no-arg constructor.
  return instantiateBean(beanName, mbd);
}

可以看出如果在RootBeanDefinition中存在factoryMethodName属性,或者说配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean实例。

再解析构造方法并进行实例化,Spring会根据参数及类型判断使用哪个构造方法再进行实例化。判断调用哪个构造方法的过程会采用缓存机制,如果已经解析过则不需要重复解析而是从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,不然则需要再次解析。

创建bean后接下来就进行属性注入,属性注入的操作在populateBean()方法中,跟进源码:

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
  PropertyValues pvs = mbd.getPropertyValues();

  if (bw == null) {
    if (!pvs.isEmpty()) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    }
    else {
      // Skip property population phase for null instance.
      return;
    }
  }

  // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  // state of the bean before properties are set. This can be used, for example,
  // to support styles of field injection.
  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);

    // Add property values based on autowire by name if applicable.
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
    }

    // Add property values based on autowire by type if applicable.
    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);
}

在populateBean方法的中的主要处理流程:

  1. InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法控制程序是否继续填充属性;
  2. 根据注入类型提取依赖的bean,并存入PropertyValues中;
  3. 应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法对属性在填充前再次处理,主要还是验证属性;
  4. 将所有PropertyValues中的属性填充到BeanWrapper中。

最后初始化bean

学过Spring的都知道bean配置时有一个init-method属性,这个属性的作用是在bean实例化前调用init-method指定的方法进行需要的实例化操作,现在就进入这个方法了;Spring中程序已经执行过bean的实例化,并且进行了属性的填充,而就在这时将会调用用户设定的初始化方法。

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
  if (System.getSecurityManager() != null) {
    AccessController.doPrivileged(new PrivilegedAction<Object>() {
      @Override
      public Object run() {
        invokeAwareMethods(beanName, bean);
        return null;
      }
    }, getAccessControlContext());
  }
  else {
    // 特殊bean处理
    invokeAwareMethods(beanName, bean);
  }

  Object wrappedBean = bean;
  if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  }

  try {
    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 = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  }
  return wrappedBean;
}

最后加载完Bean并执行完初始化操作后,一个bean的加载基本就结束了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring简单容器中的Bean基本加载过程

    本篇将对定义在 XMl 文件中的 bean,从静态的的定义到变成可以使用的对象的过程,即 bean 的加载和获取的过程进行一个整体的了解,不去深究,点到为止,只求对 Spring IOC 的实现过程有一个整体的感知,具体实现细节留到后面用针对性的篇章进行讲解. 首先我们来引入一个 Spring 入门使用示例,假设我们现在定义了一个类 org.zhenchao.framework.MyBean ,我们希望利用 Spring 来管理类对象,这里我们利用 Spring 经典的 XMl 配置文件形式进行

  • Spring多种加载Bean方式解析

    1 定义bean的方式 常见的定义Bean的方式有: 通过xml的方式,例如: <bean id="dictionaryRelMap" class="java.util.HashMap"/> 通过注解的方式,在Class上使用@Component等注解,例如 @Component public class xxxServicer{ .... } 通过在@Configuration类下的@Bean的方式,例如 @Configuration public c

  • 详解Spring中Bean的加载的方法

    之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,从之前的例子开始. Spring中加载一个bean的方式: TestBean bean = factory.getBean("testBean"); 来看看getBean(String name)方法源码, @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, nul

  • 详解Spring 中 Bean 的生命周期

    前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,直到看到了<Spring in action>这本书,书上有对Bean声明周期的大致解释,但是没有代码分析,所以就自己上网寻找资料,一定要把这个Bean生命周期弄明白! ​ 网上大部分都是验证的Bean 在面试问的生命周期,其实查阅JDK还有一个完整的Bean生命周期,这同时也验证了书是具有片面性的,最fresh 的资料还是查阅原始JDK!!! 一.Bean 的完整

  • 详解Spring中Bean的作用域与生命周期

    目录 一.Bean的作用域 二.Bean的生命周期 使用代码演示Bean的生命周期 一.Bean的作用域 通过Spring容器创建一个Bean的实例时,不仅可以完成Bean的实例化,还可以使用Bean的scope属性为bean设置作用域. 语法格式:<bean id="别名" scope="作用域" class="对应实现类"> 作用域的种类:(sing) singleton和prototype区别:(该两种比较常用) ① singl

  • 详解Spring中Bean后置处理器(BeanPostProcessor)的使用

    目录 一.BeanPostProcessor接口 二.案例 三.总结 一.BeanPostProcessor接口 Bean后置处理:对Spring 工厂创建的对象进行二次加工处理,即预初始化和后初始化. PostProcessor中文意思就是后置处理器. BeanPostProcessor 接口也被称为Bean后置处理器,通过该接口可以自定义调用初始化前后执行的操作方法. 该接口中包含了两个方法:before方法(预初始化)和after方法(后厨是化) postProcessBeforeInit

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

  • 详解Spring中Bean的生命周期和作用域及实现方式

    前言 在applicationContext.xml中配置完bean之后,Bean的声明周期状态有哪些.生命周期的各个阶段可以做什么.在applicationContext.xml配置bean的作用域有哪些.其中各个作用域代表的是什么.适用于什么情况.这篇文章做一个记录. 生命周期 初始化 可以直接查看图片,图片来自Spring Bean Life Cycle 从上图看出,Bean初始化完成包括9个步骤.其中一些步骤包括接口的实现,其中包括BeanNameAware接口,BeanFactoryA

  • 详解Spring中bean的几种注入方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入.依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Spring容器中支持的依赖注入方式主要有属性注入.构造函数注入.工厂方法注入.接下来将为大家详细介绍这三种依赖注入的方式以及它们的具体配置方法. 1.属性注入 属性注入即通过setXXX( )方法注入bean的属性值或依赖对象.由于属性注入方式具有可选择性和灵活性高的特点,因此它也是实际开发中最常用的注入方式

  • 详解Spring中bean生命周期回调方法

    生命周期回调方法 对于spring bean来讲,我们默认可以指定两个生命周期回调方法.一个是在ApplicationContext将bean初始化,包括注入对应的依赖后的回调方法:另一个是在ApplicationContext准备销毁之前的回调方法.要实现这种回调主要有三种方式:实现特定的接口.在XML配置文件中指定回调方法和使用JSR-250标准的注解. 1 实现特定接口 针对bean初始化后的回调和ApplicationContext销毁前的回调,Spring分别为我们了提供了Initia

  • 详解Spring中实现接口动态的解决方法

    前言 本文主要给大家介绍的是关于Spring实现接口动态的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍吧. 关于这个问题是因为领导最近跟我提了一个需求,是有关于实现类Mybatis的@Select.@Insert注解的功能.其是基于interface层面,不存在任何的接口实现类.因而在实现的过程中,首先要解决的是如何动态实现接口的实例化.其次是如何将使接口根据注解实现相应的功能. 声明 解决方案是基于Mybatis源码,进行二次开发实现. 解决方法 我们先来看看Mybat

  • 详解Spring中bean实例化的三种方式

    今天我想来说说如何通过xml配置来实例化bean,其实也很简单. 使用xml配置来实例化bean共分为三种方式,分别是普通构造方法创建.静态工厂创建.实例工厂创建,OK,那么接下来我们来分别看看这几种方式. 普通构造方法创建 这种创建方式使我们使用最多的一种创建方式,直接配置bean节点即可,比如我有一个User类,如下: public class User { public void add() { System.out.println("add()---------"); } }

随机推荐