Bean的实例化和生命周期

DefaultListableBeanFactory类层次结构

在开始Bean的实例化和生命周期之前有必要对Bean所处的位置以及相关的类层次结构进行了解。

下图是DefaultListableBeanFactory的类层次结构

这里写图片描述
其中有几个比较重要的类或接口需要知道:

DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry——默认的单例bean注册器,实现了SingletonBeanRegistry接口,这个类主要作为BeanFactory接口实现类的基类。注意,这个类并不关注bean defifinition或bean实例的创造过程,但是这个类维护了很多跟容器相关的Map。这个类的字段如下:

/**
 * Internal marker for a null singleton object:
 * used as marker value for concurrent Maps (which don't support null values).
 */
protected static final Object NULL_OBJECT = new Object();


/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);

/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
      Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

/** Names of beans currently excluded from in creation checks */
private final Set<String> inCreationCheckExclusions =
      Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

/** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions;

/** Flag that indicates whether we're currently within destroySingletons */
private boolean singletonsCurrentlyInDestruction = false;

/** Disposable bean instances: bean name --> disposable instance */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();

/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

其中包括持有单例bean,工厂bean等实例的map。这个类的其它方法用于操作这几个map或其它字段实现对bean实例的添加、删除等操作。

containedBeanMap用于保存bean在singletonObjects中的key名称到bean的名称集合的映射。

FactoryBeanRegistrySupport

FactoryBeanRegistrySupportDefaultSingletonBeanRegistry的子类,主要添加了对工厂bean注册的支持。

AbstractBeanFactory

这个抽象类是BeanFactory接口的基本实现,提供ConfigurableBeanFactory接口的所有实现。这个类通过父类实现对单例bean的管理,在这里BeanFactory和bean 注册表联系在一起了。AbstractBeanFactory还提供了原型bean的访问,具体代码如下:

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);
}

这是doGetBean()方法的一个代码片段,思路就是如果bean是prototype类型,就直接创建一个实例返回。

这里,isPrototype()方法是BeanDefinition接口定义的方法。

此时,BeanFactoryDefaultSingletonBeanRegistry通过AbstractBeanFactory联系起来了,通过getBean()方法(BeanFactory接口定义)获取bean实例的大致流程是:先解析bean名称获取beanName,检查DefaultSingletonBeanRegistry注册表中手动注册的单例bean缓存,如果有则返回;没有则根据beanName创建BeanDefinition实例mbd,通过mbd创建并注册bean实例。注意,创建bean实例时,会先解析并创建bean的依赖,最后创建相应的单例或者原型bean。AbstractBeanFactory并没有实现createBean()方法,这个方法由子类具体去实现

分析到这里,BeanDefinition, BeanFactoryDefaultSingletonBeanRegistry之间并没有交流,只是各自完成相应的工作,比如BeanDefinition只负责记录bean的定义,BeanFactory只负责定义容器对bean的基本操作,如获取bean实例,判断bean是单例的还是原型的,DefaultSingletonBeanRegistry只是一个注册表,它只是简单地提供了一个map用于保存对象的引用。

AbstractAutowireCapableBeanFactory

它提供了createBean()的默认实现、属性填充、装配(包括自动装配)和初始化。AbstractAutowireCapableBeanFactory基本上完成了一个容器的所有必要功能,例如bean的实例化、管理bean注册表等。这个类将依赖解析的任务交给子类去实现,以此实现自动装配。

注意,这个类并没有实现bean definition注册表的功能,这个功能是由DefaultListableBeanFactory实现的。

DefaultListableBeanFactory

一个基于bean definition对象的完全成型的bean factory。典型的使用案例是:在访问bean实例之前,先注册所有的bean definition(可以通过一个bean 定义文件读取)。在本地的bean definition表中,bean definition查询是一项资源消耗较小的操作,主要操作预先构建的bean definition元数据。DefaultListableBeanFactory是一个标准的bean factory。基于注解的或XML的bean factory要么间接调用了它或者直接继承与它,它们的不同主要在于配置文件的读取方式不同等。至此,在DefaultListableBeanFactory中知道怎么通过解析bean definition实例化并注册bean,这就是一个容器的基本功能。

Bean的生命周期

bean的生命周期如下图所示:
这里写图片描述

下面对上述的过程进行详细说明:

  1. 实例化。Spring对bean的实例化是一个比较复杂的过程。实例化bean的工作是在AbstractAutowireCapableBeanFactory类中实现的,其中createBean()方法或调用doCreateBean()实现bean的实例化、属性填充以及后置处理器的调用。途中的实例化单纯地指创建bean实例,参考代码。
  2. 属性填充。Spring将值和bean的引用注入到bean对应的属性中, 参考代码。
  3. 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法。
  4. 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入,这样bean就能感知容器的存在。
  5. 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入,这样bean就能感知应用上下文的存在。
  6. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法。
  7. 如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。
  8. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法。
  9. bean准备就绪,并将一直驻留在应用上下文中,直到应用上下文销毁。
  10. 如果bean实现了DisposableBean接口,Spring将调用它的destory()方法。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
  if (logger.isDebugEnabled()) {
    logger.debug("Creating instance of bean '" + beanName + "'");
  }
  RootBeanDefinition mbdToUse = mbd;

  // Make sure bean class is actually resolved at this point, and
  // clone the bean definition in case of a dynamically resolved Class
  // which cannot be stored in the shared merged bean definition.
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
  }

  // Prepare method overrides.
  try {
    mbdToUse.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                  beanName, "Validation of method overrides failed", ex);
  }

  try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean 
    // instance.
    // 以下方法返回一个bean的代理而不是目标bean的实例,动态代理????
    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);
  }

  // 实例化bean
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  if (logger.isDebugEnabled()) {
    logger.debug("Finished creating instance of bean '" + beanName + "'");
  }
  return beanInstance;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final                            Object[] args) throws BeanCreationException {
  // 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);
  mbd.resolvedTargetType = beanType;

  // Allow post-processors to modify the merged bean definition.
  synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      try {
        // 调用后置处理器
        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
      }
      mbd.postProcessed = true;
    }
  }

  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like 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);
      }
    });
  }

  // Initialize the bean instance.
  // bean实例初始化
  Object exposedObject = bean;
  try {
    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);
    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 {
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
}

总结一下bean实例化的内部实现主要分为以下几步:

  1. 读取配置文件(.xml)或者通过@Bean注解将配置转化成BeanDefinition,这些BeanDefinition实例会保存在DefaultListableBeanFactory的beanDefinitionMap中,bean definition描述了bean在容器中的定义。这时的BeanDefinition可能只是个半成品,因为某些XML属性配置里会有占位符变量,也可能通过注解注入值,这些变量此时不会被解析出来,需要后续处理。
  2. 在bean definition 后续处理中,容器首先扫描注册表取出工厂后处理器,对注册表中的BeanDefinition进行加工处理,把占位符替换成真正的值,产生成品的BeanDefinition
  3. 通过反射机制扫描BeanDefinitionRegistry所有属性编辑器的bean类,并把这些bean放到spring容器的属性编辑器注册表(PropertyEditorRegistry)中。
  4. Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手对bean的实例化工作。这里的实例化只是相当于new了一个新对象一样,也就是说,只是跑一个构造函数,不会具体的为属性设置值。
  5. 实例化的过程中,spring容器使用BeanWrapper对bean进行封装,BeanWrapper结合BeanDefinition和属性编辑器注册表中的属性编辑器完成bean的属性设置工作。
  6. 最后调用BeanPostProcessor回调函数对bean进行后置处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值