Spring源碼分析(一) 從Spring Bean的生命周期談起

Spring Bean的生命周期真的是面試的時(shí)候關(guān)于Spring的最高頻的考點(diǎn)之一了,筆者曾經(jīng)被這個(gè)問(wèn)題問(wèn)懵了不止一次,一直記不住那一大串的步驟,但實(shí)際上嘗試去死記硬背那些步驟的我是錯(cuò)誤的,表面上看只是背誦一個(gè)流程,實(shí)際上,這個(gè)流程牽扯到的知識(shí)點(diǎn)可是很多而且很有意思的。

下面這個(gè)圖我想很多人應(yīng)該都看過(guò)相同的或者相似的:

Spring Bean的生命周期

看起來(lái)還是挺長(zhǎng)的對(duì)吧,但是我們其實(shí)可以把它劃分成下面四個(gè)大的步驟:

  1. 實(shí)例化Bean
  2. 設(shè)置對(duì)象屬性,依賴注入
  3. 初始化
  4. destroy:bean的銷(xiāo)毀

接下來(lái),我會(huì)根據(jù)這個(gè)步驟,一步步的講解相關(guān)的知識(shí)點(diǎn),從生命周期出發(fā),將Spring中重要的類(lèi)或接口來(lái)一一說(shuō)明。

一、實(shí)例化Bean

這第一步,容器通過(guò)獲取BeanDefinition對(duì)象中的信息進(jìn)行實(shí)例化。并且這一步僅僅是簡(jiǎn)單的實(shí)例化,并未進(jìn)行依賴注入,可以理解成new xx()。但要注意的是,對(duì)于BeanFactory容器和ApplicationContext容器它們的實(shí)例化是有區(qū)別的。

  • 對(duì)于BeanFactory容器,當(dāng)客戶向容器請(qǐng)求一個(gè)尚未初始化的bean時(shí),或初始化bean的時(shí)候需要注入另一個(gè)尚未初始化的依賴時(shí),容器就會(huì)調(diào)用createBean()進(jìn)行實(shí)例化。
  • 對(duì)于ApplicationContext容器,當(dāng)容器啟動(dòng)結(jié)束后,便實(shí)例化所有的bean。

那么既然提到了BeanFactory和ApplicationContext,我就對(duì)這兩個(gè)接口也簡(jiǎn)單介紹一下。它們分別位于org.springframework.beansorg.springframework.context兩個(gè)包下,而這兩個(gè)包,正是Spring IoC容器的基礎(chǔ)。BeanFactory提供了框架最基礎(chǔ)的一些功能,包括IOC的配置機(jī)制,提供Bean的各種定義,建立Bean之間的依賴關(guān)系等。ApplicationContext繼承了BeanFactory,因此它擁有BeanFactory的所有功能,但它本身還繼承了一些其他的接口,比如消息資源配置,事件發(fā)布等。

BeanFactory是Spring框架的基礎(chǔ)設(shè)施,面向Spring。ApplicationContext面向Spring框架的開(kāi)發(fā)者。所以我們平常開(kāi)發(fā)的過(guò)程中其實(shí)也可以發(fā)現(xiàn)到,我們更多的會(huì)用上的是ApplicationContext相關(guān)的工具,而不是BeanFactory。

除此之外,在實(shí)例化這個(gè)步驟的前后,實(shí)際上還有隱藏任務(wù),牽扯到的接口叫做InstantiationAwareBeanPostProcessor。它繼承了BeanPostProcessor。可能有的人不知道BeanPostProcessor這個(gè)接口,那么我就先介紹下這個(gè)。

BeanPostProcessor也是位于org.springframework.beans下,又叫做后置處理器,它定義了一系列的回調(diào)方法用來(lái)讓使用者可以自定義Bean實(shí)例化或者依賴解析等的邏輯。它本身只有兩個(gè)方法: postProcessBeforeInitialization和postProcessAfterInitialization。如方法名所說(shuō),定義Bean的初始化前后的邏輯。這個(gè)接口在整個(gè)生命周期中都有著關(guān)聯(lián)。

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

不要弄混了BeanPostProcessor中的方法我說(shuō)的是初始化前后,而生命周期的第一步是實(shí)例化。這里用到的InstantiationAwareBeanPostProcessor它有自己的對(duì)于實(shí)例化邏輯處理的兩個(gè)方法。postProcessBeforeInstantiation和postProcessAfterInstantiation。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        return null;
    }
}

通過(guò)查找調(diào)用postProcessBeforeInstantiation這個(gè)方法的地方,會(huì)追溯到創(chuàng)建Bean的關(guān)鍵方法。就是AbstractAutowireCapableBeanFactory下的createBean()。

/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
    // 里面的代碼我下面挑出重點(diǎn)的步驟一步步的貼出來(lái)
}

通過(guò)查看源碼對(duì)于此方法的注釋就知道它有多重要了。它可以創(chuàng)建Bean的實(shí)例,對(duì)其進(jìn)行屬性填充,調(diào)用BeanPostProcesser等。第一步我們注意到的代碼應(yīng)該是

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);

它實(shí)際上是比我們上面生命周期的圖示還要之前的一步,就是獲取BeanDefinition對(duì)象中的信息來(lái)對(duì)Bean class進(jìn)行解析。所謂BeanDefinition,它就是對(duì)于Bean的一個(gè)描述。它包含了Bean的一些基礎(chǔ)信息,如Bean的name、Bean的作用域、和其他Bean的關(guān)系等等。解析完之后再進(jìn)行到下一步。

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
  return bean;
}

這個(gè)注釋其實(shí)也給出了它的意義了,它給予BeanPostProcessor們一個(gè)機(jī)會(huì),可以返回一個(gè)代理而不是目標(biāo)bean的實(shí)例。但我們翻閱到上面的InstantiationAwareBeanPostProcessor對(duì)于此方法的實(shí)現(xiàn),會(huì)發(fā)現(xiàn)它返回的是null,所以默認(rèn)的邏輯這里是不會(huì)return的。所以我們會(huì)走到下一步,doCreateBean。

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

進(jìn)入到這個(gè)方法,它的第一行注釋也是簡(jiǎn)單粗暴,就是來(lái)實(shí)例化Bean的。

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}

但可以發(fā)現(xiàn),createBeanInstance()這個(gè)方法返回的是一個(gè)BeanWrapper對(duì)象。BeanWrapper是對(duì)Bean的一個(gè)包裝,它可以設(shè)置獲取被包裝的對(duì)象,獲取被包裝bean的屬性描述器等。我們平時(shí)開(kāi)發(fā)是不會(huì)直接使用這個(gè)類(lèi)的。通過(guò)createBeanInstance()這個(gè)方法的注釋我們也能明白,它的作用是對(duì)于指定的bean生成一個(gè)新的實(shí)例,這里可以使用合適的實(shí)例化策略,比如工廠方法,構(gòu)造器注入或者簡(jiǎn)單實(shí)例化等。

    /**
     * Create a new instance for the specified bean, using an appropriate instantiation strategy:
     * factory method, constructor autowiring, or simple instantiation.
     */
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    //代碼我也不貼了
  }

接下來(lái)這段代碼,注釋也有說(shuō)明,就是將調(diào)用各種postProcessers來(lái)進(jìn)行屬性的合并,這里會(huì)進(jìn)行一些注解的掃描。

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

再然后是一段跟一個(gè)面試題緊密相關(guān)的代碼,那就是Spring如何解決循環(huán)依賴。因?yàn)楸疚牡闹攸c(diǎn)是講bean的生命周期,本來(lái)準(zhǔn)備一起寫(xiě)完的,但寫(xiě)著寫(xiě)著發(fā)現(xiàn)要說(shuō)的太多了,后面我會(huì)另外單獨(dú)寫(xiě)文章來(lái)講述如何解決循環(huán)依賴的問(wèn)題。

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

二、設(shè)置對(duì)象屬性,依賴注入

結(jié)束了實(shí)例化之后,我們繼續(xù)在createBean這個(gè)方法上繼續(xù)往下走,到了populateBean這一步。

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

對(duì)于這個(gè)方法,我們已開(kāi)始注意到的就是我之前說(shuō)過(guò)在實(shí)例化前后都是存在著隱藏任務(wù),上面提到了實(shí)例化之前的postProcessBeforeInstantiation,那么如今已經(jīng)實(shí)例化了,現(xiàn)在出現(xiàn)了實(shí)例化之后的方法postProcessAfterInstantiation,這里也是給InstantiationAwareBeanPostProcessors一個(gè)機(jī)會(huì)去自定義屬性被賦值后的方式。在后面代碼中回去執(zhí)行這個(gè)后置處理器的方法。

// 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.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
         return;
      }
   }
}

繼續(xù)往下,我們能看到一個(gè)熟悉的單詞,Autowire,不過(guò)這里是獲取當(dāng)前注入的方式,根據(jù)byName還是byType來(lái)獲得要注入的屬性。這里我也不深入說(shuō)明了。

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
   // Add property values based on autowire by name if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
   }
   // Add property values based on autowire by type if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
   }
   pvs = newPvs;
}

然后就是populateBean的第一步我就提到的方法,如果存在后置處理器,那么會(huì)進(jìn)行屬性的校驗(yàn)和處理,同時(shí)第二個(gè)布爾變量是用來(lái)判斷是否進(jìn)行依賴校驗(yàn)的。

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
   if (pvs == null) {
      pvs = mbd.getPropertyValues();
   }
   for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
         if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
         }
         pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            return;
         }
      }
      pvs = pvsToUse;
   }
}
if (needsDepCheck) {
   if (filteredPds == null) {
      filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
   }
   checkDependencies(beanName, mbd, filteredPds, pvs);
}

最后一步,就是將前面這些步驟得到的屬性進(jìn)行注入了。

if (pvs != null) {
   applyPropertyValues(beanName, mbd, bw, pvs);
}

三、初始化

populateBean()方法結(jié)束后開(kāi)始進(jìn)入initializeBean()方法,正如方法名所表達(dá)的,就是bean的初始化。注意初始化和實(shí)例化不是一個(gè)意思,在生命周期中bean是先進(jìn)行實(shí)例化再進(jìn)行初始化的。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      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;
}

首先第一步,先不管那些安全機(jī)制的代碼,我們要關(guān)注的是invokeAwareMethods(beanName, bean);這行代碼,這里就是調(diào)用所有的Aware類(lèi)型的接口。Spring中Aware類(lèi)型的接口可以讓我們獲取容器中的一些資源。

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

比如這里面出現(xiàn)的有三種Aware類(lèi)型的接口: BeanNameAware, BeanClassLoaderAware,BeanFactoryAware。它們根據(jù)bean實(shí)現(xiàn)了某個(gè)接口來(lái)完成不同的工作。

  • 如果實(shí)現(xiàn)了BeanNameAware接口,則通過(guò)setBeanName()方法將beanName設(shè)置給這個(gè)bean
  • 如果實(shí)現(xiàn)了BeanClassLoaderAware接口,則通過(guò)setBeanClassLoader()方法,將ClassLoader傳入
  • 如果實(shí)現(xiàn)了BeanFactoryAware接口,則通過(guò)setBeanFactory()方法,將BeanFactory容器實(shí)例傳入

結(jié)束完Aware接口的調(diào)用,繼續(xù)往下走,到了applyBeanPostProcessorsBeforeInitialization()這個(gè)方法(因?yàn)閕f判斷是這個(gè)bean是空或者這個(gè)bean是否是synthetic的,就是是否是應(yīng)用自己定義的,顯然我們自己的bean不是,所以if條件后半部分會(huì)是true)。這個(gè)方法就是處理我之前有提到過(guò)的BeanPostProcessor的postProcessBeforeInitialization()方法。如果Bean實(shí)現(xiàn)了BeanPostProcessor接口,那么就會(huì)執(zhí)行這個(gè)方法

之后,流程來(lái)到了invokeInitMethods()這一步,這一步就是執(zhí)行bean的自定義初始化方法。如果bean實(shí)現(xiàn)了InitializingBean接口,就需要重寫(xiě)afterPropertiesSet()方法,則invokeInitMethods的時(shí)候會(huì)調(diào)用這個(gè)重寫(xiě)后的afterPropertiesSet()方法,如果bean自定義了init方法,則會(huì)調(diào)用指定的init方法(可通過(guò)xml中配置bean的init-method屬性實(shí)現(xiàn)),這兩個(gè)方法的先后順序是: afterPropertiesSet在前,自定義init在后。

繼續(xù)下去就是applyBeanPostProcessorsAfterInitialization()方法了,和前面的applyBeanPostProcessorsBeforeInitialization()方法前后呼應(yīng),這個(gè)就不必多說(shuō)了。

四、銷(xiāo)毀

后面的一段代碼還是跟處理循環(huán)依賴有關(guān)系,就先不多說(shuō),直接到最后一步,registerDisposableBeanIfNecessary().

銷(xiāo)毀這一步其實(shí)就是可以讓我們自己自定義bean的銷(xiāo)毀方法,用到的關(guān)鍵的接口是DisposableBean,它和InitializingBean接口類(lèi)似,只是一個(gè)初始化階段的init,一個(gè)是結(jié)束階段的destroy。

/**
 * Add the given bean to the list of disposable beans in this factory,
 * registering its DisposableBean interface and/or the given destroy method
 * to be called on factory shutdown (if applicable). Only applies to singletons.
 * @param beanName the name of the bean
 * @param bean the bean instance
 * @param mbd the bean definition for the bean
 * @see RootBeanDefinition#isSingleton
 * @see RootBeanDefinition#getDependsOn
 * @see #registerDisposableBean
 * @see #registerDependentBean
 */
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
   AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
   if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
      if (mbd.isSingleton()) {
         // Register a DisposableBean implementation that performs all destruction
         // work for the given bean: DestructionAwareBeanPostProcessors,
         // DisposableBean interface, custom destroy method.
         registerDisposableBean(beanName, new DisposableBeanAdapter(
               bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
      }
      else {
         // A bean with a custom scope...
         Scope scope = this.scopes.get(mbd.getScope());
         if (scope == null) {
            throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
         }
         scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
               bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
      }
   }
}

代碼示例

上面一大段一大段的源碼可能看著讓人有點(diǎn)難受,不如直接寫(xiě)個(gè)demo輕松一下。因?yàn)橹皇潜憩F(xiàn)一下生命周期,那么我們的依賴就很簡(jiǎn)單,spring-context和spring-beans即可。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

我們先定義一個(gè)自定義的后置處理器,為了表現(xiàn)初始化前后和實(shí)例化前后的流程,實(shí)現(xiàn)InstantiationAwareBeanPostProcessor接口,并重寫(xiě)postProcessBeforeInstantiation()/postProcessAfterInstantiation()/postProcessBeforeInitialization()/postProcessAfterInitialization()這四個(gè)方法。

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println(beanName + "實(shí)例化前");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "實(shí)例化后");
        return false;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "初始化前");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "初始化后");
        return null;
    }

}

再定義一個(gè)“常規(guī)”的Bean,但我們也為了反應(yīng)初始化和銷(xiāo)毀的幾個(gè)操作,讓他實(shí)現(xiàn)了InitializingBean, DisposableBean, BeanNameAware三個(gè)接口。并實(shí)現(xiàn)對(duì)應(yīng)的方法,Aware接口這里我就只實(shí)現(xiàn)一個(gè)了,只是為了表現(xiàn)注入Aware接口那個(gè)步驟。

public class DemoBean implements InitializingBean, DisposableBean, BeanNameAware {

    public DemoBean() {
        System.out.println("demoBean實(shí)例化");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("demoBean afterPropertiesSet");
    }

    public void init() {
        System.out.println("demoBean init");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("demoBean destroy");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("BeanNameAware setBeanName: "+ s);
    }
}

配置文件很簡(jiǎn)單,就兩個(gè)bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <beans>
        <bean name="myInstantiationAwareBeanPostProcessor" class="cn.leafw.spring.beans.MyInstantiationAwareBeanPostProcessor" />
        <bean name="demoBean" class="cn.leafw.spring.beans.DemoBean" init-method="init">
        </bean>
    </beans>
</beans>

測(cè)試類(lèi)也很簡(jiǎn)單粗暴,就單純啟動(dòng)和結(jié)束。

public class Test {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml");
        applicationContext.registerShutdownHook();
    }
}

點(diǎn)擊運(yùn)行,接下來(lái)就是意料之中的結(jié)果輸出:

測(cè)試結(jié)果

因?yàn)閷傩宰⑷氩环奖阍谶@里面進(jìn)行測(cè)試,但大家知道是在實(shí)例化和初始化之間就好。所以其實(shí)總的來(lái)說(shuō),Spring的生命周期理解起來(lái)不算很難,但大家對(duì)生命周期里面關(guān)鍵的接口或者類(lèi)要有印象,ApplicationContext和BeanFactory就不用多說(shuō),BeanPostProcessor是一定要知道的,Spring中的很多功能的實(shí)現(xiàn)都跟其有關(guān)。比如@Autowired注解的原理,數(shù)據(jù)校驗(yàn)Validate的原理,都是有對(duì)應(yīng)的處理器。

這篇博客寫(xiě)了我挺久的時(shí)間,就是越寫(xiě)發(fā)現(xiàn)自己對(duì)Spring的了解越淺薄,本以為啃完了Spring文檔的我應(yīng)該是能輕松看懂源碼,但實(shí)際上還是有點(diǎn)吃力的,但看懂了之后真的神清氣爽,后面還會(huì)繼續(xù)在這個(gè)坑里多填一點(diǎn)東西,學(xué)到的越多發(fā)現(xiàn)不會(huì)的越多,一起進(jìn)步吧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容