细谈Bean的实例化过程

本文详细探讨了Spring框架中Bean的实例化过程,从ClassPathXmlApplicationContext的构造函数开始,深入到BeanDefinition的注册,接着分析了Bean的实例化逻辑,包括getBean方法的调用、createBean()方法中的各个步骤,如对象的创建、属性设置、BeanPostProcessor处理、Aware接口的检查、初始化方法的调用等,直至Bean可以正常使用和销毁的整个生命周期过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

细谈Bean的实例化过程


我们都知道,在执行以下的一行代码后,我们就可以调用在knight.xml文件中配置的bean了。

那么context的内部究竟长什么样?它又是在哪里,以何种方式实现了依赖注入?

ApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");

以ClassPathXmlApplicationContext为例追溯Bean的实例化过程

声明:源代码为Spring 5.0版本

ClassPathXmlApplicationContext的继承与实现关系

在这里插入图片描述

DefaultListableBeanFactory的继承与实现关系

在这里插入图片描述

ClassPathXmlApplicationContext的构造函数

首先查看ClassPathXmlApplicationContext的构造函数:

// org.springframework.context.support.ClassPathXmlApplicationContxt

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
   this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
}

可以看到,在其构造函数中,调用了refresh()方法。该方法定义在ClassPathXmlApplicationContext的父父…父接口AbstractApplicationContext中:

// org.springframework.context.support.AbstractApplicationContext

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.                 (1)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.                 (2)
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
         contextRefresh.end();
      }
   }
}

我们知道,对Bean的实例化操作是由BeanFactory实现的,ApplicationContext在此之外扩展了一些功能。在refresh()方法中和bean实例化相关的代码主要为(1),(2)两行。

我们还知道,BeanFactory初始化Bean分为两步

第一步是容器的启动阶段:容器加载Configuration MetaData,使用工具类(BeanDefinitionReader)解析元数据,注册BeanDefinition到相应的BeanDefinitionRegistry。

第二步是Bean的实例化阶段:当某个请求调用getBean()方法时,根据BeanDefinition实例化这个Bean。

AbstractContext的refresh方法中这两行代码正好对应了这两个操作:

第一行代码初始化一个BeanFactory,用它来注册所有的BeanDefinition

第二行代码集中调动getBean方法,实例化所有Bean

(这也是为什么BeanFactory延迟初始化,而ApplicationContext在一开始就初始化)

注册BeanDefinition的逻辑所在

我们先看ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 这行:

// org.springframework.context.support.AbstractApplicationContext

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

getBeanFactory()就是返回类中定义的BeanFactory属性,我们主要关注refreshBeanFactory()方法

该方法的实现写在AbstractRefreshableApplicationContext类里:

(搞不清这几个类之间关系的可以拉到前面再看一遍类图)

// org.springframework.context.support.AbstractRefreshableApplicationContext

/**
 * This implementation performs an actual refresh of this context's underlying
 * bean factory, shutting down the previous bean factory (if any) and
 * initializing a fresh bean factory for the next phase of the context's lifecycle.
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

在refreshBeanFactory()方法中,首先判断是否已经初始化了一个BeanFactory,若有,就destroy掉。

先创建了一个DefaultListableBeanFactory对象,然后调用loadBeanDefinitions()方法

我们先看loadBeanDefinitions()方法,该方法的实现和你使用哪种Configuration MetaData有关,我们使用Xml文件加载配置,方法的实现写在AbstractXmlApplicationContext类中:

// org.springframework.context.support.AbstractXmlApplicationContext

/**
 * Loads the bean definitions via an XmlBeanDefinitionReader.
 *@seeorg.springframework.beans.factory.xml.XmlBeanDefinitionReader
 *@see#initBeanDefinitionReader
 *@see#loadBeanDefinitions
 */
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);
   loadBeanDefinitions(beanDefinitionReader);
}

/**
 * Initialize the bean definition reader used for loading the bean
 * definitions of this context. Default implementation is empty.
 *<p>Can be overridden in subclasses, e.g. for turning off XML validation
 * or using a different XmlBeanDefinitionParser implementation.
 *@paramreaderthe bean definition reader used by this context
 *@seeorg.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
 */
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
   reader.setValidating(this.validating);
}

/**
 * Load the bean definitions with the given XmlBeanDefinitionReader.
 *<p>The lifecycle of the bean factory is handled by the {@link#refreshBeanFactory}
 * method; hence this method is just supposed to load and/or register bean definitions.
 *@paramreaderthe XmlBeanDefinitionReader to use
 *@throwsBeansException in case of bean registration errors
 *@throwsIOException if the required XML document isn't found
 *@see#refreshBeanFactory
 *@see#getConfigLocations
 *@see#getResources
 *@see#getResourcePatternResolver
 */
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
   if (configResources != null) {
      reader.loadBeanDefinitions(configResources);
   }
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      reader.loadBeanDefinitions(configLocations);
   }
}

该方法的逻辑大概如下:

创建一个BeanDefinitionReader实例对象⇒配置并初始化该reader对象⇒使用reader对象根据Resources加载BeanDefinition

BeanDefinitionReader是如何解析xml文件的就不去探讨了,接下来我们研究一下DefaultListableBeanFactory类

实例化Bean的逻辑——getBean方法是怎么调用到的

我们回到AbstractApplicationContext类的refresh()方法,该方法的(2)代码如下所示:

finishBeanFactoryInitialization(beanFactory);

根据官方注释,这行代码实例化所有的非延迟加载的单例对象

// org.springframework.context.support.AbstractApplicationContext

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
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)) {
      beaFactory.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(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

	 // (3)
   // 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();

   // (4)
   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}

(3)处的代码,获取所有在类加载时织入的bean的名称,然后调用它们的getBean方法。

当然我们的重点不在这,而是在(4)处的代码:beanFactory.preInstantiateSingletons();

在这一步,我们所定义的所有非懒加载的单例对象,都将被实例化。

该方法的方法体写在DefaultListableBeanFactory类里

// org.springframework.beans.factory.support.DefaultListableBeanFactory

@Override
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.
   List<String> beanNames = new ArrayList<>(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()) {
         // 如果该bean是一个factorybean对象,那么在beanName前加一个前缀'&'再实例化
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX+ beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               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());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
	       // 不是factorybean,即一般对象,调用getbean方法实例化
         else {
            getBean(beanName);
         }
      }
   }
   ...
}

看中间有中文注释的那部分,首先筛查出需要预实例化的bean:

  • 不是抽象的
  • scope是singleton
  • 不是声明为延迟初始化的

如果该bean是factoryBean类型,那么在beanName上加上一个&前缀再实例化;如果非factorybean,那么直接调用getBean()方法

getBean()

getBean()方法实现在AbstractBeanFactory里:

// org.springframework.beans.factory.support.AbstractBeanFactory

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

doGetBean()的实现也在AbstractBeanFactory类里,它的源码太长了,我就不贴了。

大致逻辑是:

调用getSingleton(beanName)方法获取该bean的单例对象,如果不是null,那么会返回该对象;如果该对象为空,那么:

  1. 通过beanName获取BeanDefinition,并调用getBean获取该Bean所依赖的其他bean。
  2. 注册所依赖的bean
  3. 如果beanDefinition是singleton类型,那么调用createbean()方法创建一个bean对象,并将单例对象引用指向这个对象。
  4. 如果beanDefinition是prototype类型,那么创建新对象并返回。

还是贴个代码框架吧,删掉了和主要逻辑无关的代码:

// org.springframework.beans.factory.support.AbstractBeanFactory

protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {

   String beanName = transformedBeanName(name);
   Object beanInstance;

   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      ...
      beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }
   else {
			...
      try {
				 ...
         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // Guarantee initialization of beans that the current bean depends on.
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                   ...
		               registerDependentBean(dep, beanName);
               try {
	                 getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
	                 ... 
							 }
            }
         }
         // Create bean instance.
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            beanInstance = 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);
            }
            beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         ...
   }

   return adaptBeanInstance(name, beanInstance, requiredType);
}

真正的Bean实例化逻辑——createBean()

createBean()的实现写在AbstractAutowireCapableBeanFactory(DefaultListableBeanFactory的父类),该方法调用了doCreateBean方法来实例化单例对象

doCreateBean()代码如下所示:

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@codepostProcessBeforeInstantiation} callbacks.
 *<p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 *@parambeanNamethe name of the bean
 *@parammbdthe merged bean definition for the bean
 *@paramargsexplicit arguments to use for constructor or factory method invocation
 *@returna new instance of the bean
 *@throwsBeanCreationException if the bean could not be created
 *@see#instantiateBean
 *@see#instantiateUsingFactoryMethod
 *@see#autowireConstructor
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      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.isTraceEnabled()) {
         logger.trace("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      populateBean(beanName, mbd, instanceWrapper);
      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<>(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 " +
                     "'getBeanNamesForType' 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的实例化过程:

在这里插入图片描述

(图源《Spring揭秘》)

1. 实例化bean对象

这一部分的代码就写在doCreateBean方法内

容器调用了createBeanInstance()方法,createBeanInstance()方法又调用了instantiateBean方法,instantiateBean()代码如下所示:

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      if (System.getSecurityManager() != null) {
         beanInstance = AccessController.doPrivileged(
               (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
               getAccessControlContext());
      }
      else {
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
   }
}

可以看到在该方法中,调用了getInstantiationStrategy().instantiate(…)方法,由方法名可以看出,容器使用了策略模式。默认情况下,容器内部采用CglibSubclassingInstantiationStrategy。该策略类使用反射方式生成类,并借助Cglib的动态字节码生成功能,可以动态生成某个类的子类。

该方法返回一个BeanWrapper对象,BeanWrapper是对Bean的一个包装,可以设置或获取bean的相应属性值。

2. 设置对象属性

instantiateBean()创建完BeanWrapper后不是立即返回,而是调用initBeanWraper()方法

initBeanWrapper方法实现于AbstractBeanFactory类中,因为BeanWrapper也实现自PropertyEditorRegistry接口,所以可以复制一份PropertyEditor,用于转换类型、设置对象属性。

/**
 * Initialize the given BeanWrapper with the custom editors registered
 * with this factory. To be called for BeanWrappers that will create
 * and populate bean instances.
 *<p>The default implementation delegates to {@link#registerCustomEditors}.
 * Can be overridden in subclasses.
 *@parambwthe BeanWrapper to initialize
 */
protected void initBeanWrapper(BeanWrapper bw) {
   bw.setConversionService(getConversionService());
   registerCustomEditors(bw);
}

3. BeanPostProcessor前置处理和检查Aware接口并设置相关依赖

这两步放在一块讲,因为在代码中的执行顺序与流程图的顺序相反。

先执行BeanPostProcessor前置处理:

// 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.isTraceEnabled()) {
      logger.trace("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

然后执行initialBean()方法

initalBean()方法中共调用了三个其他方法:

  • invokeAwareMethods(beanName, bean)
  • invokeInitMethods(beanName, wrappedBean, mbd)
  • applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)

invokeAwareMethods方法即检查Aware相关接口并设置依赖:

private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

4. 检测是否是InitializingBean以决定是否调用afterPropertiesSet()

initalBean()所调用的第二个方法invokeInitMethods代码如下所示:

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

InitializingBean是容器内部广泛使用的一个对象声明周期接口,如果检测到当前对象实现了这个接口,会调用afterPropertiesSet()方法进一步调整对象实例的状态。比如,在有些情况下,某个对象实例化完成后,还不能处于可以使用的状态,这时就应该让该对象实现这个接口,并在afterPropertiesSet方法中定义后续处理。

5. init-method

invokeInitMethod方法中调用了invokeCustomInitMethod方法执行用户定义的初始化操作

在xml中,我们通过标签定义需要在初始化后、使用之前调用的方法

6. BeanPostProcessor后续处理

initalBean()调用的第三个方法——applyBeanPostProcessorsAfterInitialization完成了后续处理

7. 可以使用了!

initalBean()执行完成后,会返回一个Object对象,如果不是循环依赖,此时该object已经可以使用了。

如果是循环依赖,因为之前创建的object的依赖为空,所以要更新这个对象。

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<>(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 " +
                  "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
         }
      }
   }
}

8. DisposableBean与destory-method

doCreateBean的最后几行代码,如果bean实现了DisposableBean接口,或通过destory-method定义了对象销毁方法,那么会为该实例注册一个用于对象销毁的回调。在这些对象实例销毁之前,执行回调。

// Register bean as disposable.
try {
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
   throw new BeanCreationException(
         mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值