Spring Bean生命週期

Spring Bean生命週期總體可分爲如下幾個階段:html

  • Spring Bean元信息處理階段
  • Spring Bean實例化階段
  • Spring Bean初始化階段
  • Spring Bean銷燬階段
  • Spring Bean垃圾收集階段

Spring Bean生命週期處理是Spring應用上下文生命週期的一部分,能夠參考此文瞭解Spring應用上下文生命週期。express

Spring Bean元信息處理階段

Spring Bean元信息處理階段能夠細分爲如下幾個階段:緩存

  • Spring Bean元信息解析階段
  • Spring BeanDefinition註冊階段
  • Spring BeanDefinition合併階段

Spring Bean元信息解析階段

在Spring應用上下文生命週期裏有一個建立BeanFactory階段,在這個階段會建立底層IoC容器BeanFactory,而後會進行一些別的操做,其中一個操做就是處理Spring Bean元信息,代碼以下所示:數據結構

    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

能夠看出這個方法會調用方法loadBeanDefinitions加載Spring Bean元信息: BeanDefinition。app

loadBeanDefinitions在子類AbstractXmlApplicationContext有一個實現,代碼以下所示:ide

    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        //建立XmlBeanDefinitionReader解析XML配置文件讀取Spring Bean元信息
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        //設置Spring Bean元信息讀取配置
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        //初始化XmlBeanDefinitionReader
        initBeanDefinitionReader(beanDefinitionReader);
     //加載Spring Bean元信息 loadBeanDefinitions(beanDefinitionReader); }
    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); } }

這一塊代碼邏輯比較簡單,就是使用XmlBeanDefinitionReader加載Spring Bean元信息,這裏指處理了XML配置的元信息。函數

還有一種經常使用Spring Bean元信息配置是註解,針對這種Spring Bean元信息配置的解析,在AnnotationConfigApplicationContext進行處理,代碼以下所示:post

    public AnnotationConfigApplicationContext(String... basePackages) {
        this();
        scan(basePackages);
        refresh();
    }

AnnotationConfigApplicationContext一個構造器裏會調用scan方法掃描指定包路徑,會使用ClassPathBeanDefinitionScanner的scan能力掃描具備某些註解的類,把這些類加載爲Spring Bean元信息。ui

Spring BeanDefinition註冊階段

上面着重介紹了Spring Bean元信息解析,Spring Bean元信息解析以後,就要註冊並保存起來,方便後續使用。this

Spring具備一個數據結構BeanDefinitionRegistry,解析後的BeanDefinition會註冊到BeanDefinitionRegistry,BeanDefinitionRegistry是一個接口,一個典型的實現類是DefaultListableBeanFactory。

DefaultListableBeanFactory裏的registerBeanDefinition方法實現以下所示(這裏刪除了一些打印日誌分支):

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
     //校驗入參
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    
     //判斷BeanDefinition是不是AbstractBeanDefinition類或子類的對象,若是是,進行校驗
if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } }
     //判斷beanName對應BeanDefinition是否存在 BeanDefinition existingDefinition
= this.beanDefinitionMap.get(beanName);
     //若是已經存在,判斷是否容許覆蓋,這裏覆蓋是指一個beanName有兩個不一樣BeanDefinition,默認容許
if (existingDefinition != null) {
       //若是不容許覆蓋,拋出異常
if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); }
       //若是容許覆蓋,覆蓋配置 this.beanDefinitionMap.put(beanName, beanDefinition); } else {
       //判斷是否已經有Bean被建立了
if (hasBeanCreationStarted()) { //若是是就不能修改以前集合,須要全量覆蓋 synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { //若是不是就修改以前集合 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; }
     //判斷是否存在這個配置且已經建立單例Bean
if (existingDefinition != null || containsSingleton(beanName)) {
       //若是是就清除緩存 resetBeanDefinition(beanName); } }

Spring BeanDefinition合併階段

Spring BeanDefinition在用來實例化前,還須要作的一件事就是Spring BeanDefinition合併。

在底層IoC容器一般會有兩種BeanDefinition,一個是GenericBeanDefinition,一個是RootBeanDefinition,一個Bean在實例化前,對應BeanDefinition都要轉化成RootBeanDefinition。

GenericBeanDefinition保存原始的Spring Bean元信息,能夠指定父Bean的beanName,可是不會繼承父Bean的屬性,還不具有實例化的能力。

GenericBeanDefinition在合併以後會變成RootBeanDefinition,這時RootBeanDefinition不會保存父Bean的beanName,可是會從父Bean繼承屬性。

就算一個GenericBeanDefinition沒有父Bean也須要轉換成RootBeanDefinition。

BeanDefinition合併操做一般在實例化前進行,ConfigurableBeanFactory#getMergedBeanDefinition方法會合並對應BeanDefinition而且返回,getMergedBeanDefinition(AbstractBeanFactory)代碼以下所示:

    public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
        String beanName = transformedBeanName(name);
        //判斷當前BeanFactory不存在對應BeanDefinition,從父BeanFactory獲取合併後的BeanDefinition
        if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
            return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
        }
        //從當前BeanFactory獲取合併後的BeanDefintion
        return getMergedLocalBeanDefinition(beanName);
    }
    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        //從緩存裏獲取RootBeanDefinition
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
     //若是不是空而且不須要再次合併,返回緩存的RootBeanDefinition
if (mbd != null && !mbd.stale) { return mbd; }
     //返回合併的BeanDefinition,入參是beanName、GenericBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }

最後會進到下面這個方法:

    protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {

        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;
            RootBeanDefinition previous = null;

            //加鎖後再從緩存裏查詢一次,dcl
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }

       //若是獲取不到或者須要再次合併,執行合併BeanDefinition邏輯
if (mbd == null || mbd.stale) { previous = mbd; if (bd.getParentName() == null) { //若是沒有父beanName,直接生成RootBeanDefinition if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { //若是有父beanName,須要用父BeanDefinition合併生成RootBeanDefinition BeanDefinition pbd; try { String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) {
                 //用parentBeanName獲取BeanDefinition pbd
= getMergedBeanDefinition(parentBeanName); } else { BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } //用parentBeanName獲取RootBeanDefinition建立RootBeanDefinition mbd = new RootBeanDefinition(pbd);
           //用子BeanDefinition覆蓋RootBeanDefinition mbd.overrideFrom(bd); }
//設置scope if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(SCOPE_SINGLETON); } if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } //把RootBeanDefinition放到緩存 if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } } if (previous != null) { copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } }

Spring Bean實例化階段

Spring Bean實例化階段能夠細分爲如下幾個階段:

  • Spring Bean Class加載階段
  • Spring Bean實例化階段
  • Spring Bean實例化前階段
  • Spring Bean實例化後階段
  • Spring Bean屬性賦值前階段
  • Spring Bean賦值階段

Spring Bean Class加載階段

Spring Bean Class加載方法是AbstractBeanFactory#resolveBeanClass,代碼以下所示:

 resolveBeanClass方法會使用RootBeanDefinition裏記錄的beanClassName加載對應類,保存到RootBeanDefinition而且返回。

    protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
            throws CannotLoadBeanClassException {

        try {
            if (mbd.hasBeanClass()) {
         //判斷RootBeanDefinition裏關聯了class,直接返回
return mbd.getBeanClass(); } if (System.getSecurityManager() != null) {
         //加載對應class
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else {
         //加載對應class
return doResolveBeanClass(mbd, typesToMatch); } } catch (PrivilegedActionException pae) { ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (LinkageError err) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); } }
    private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
            throws ClassNotFoundException {
     //獲取當前類加載器
        ClassLoader beanClassLoader = getBeanClassLoader();
     //定義動態類加載器,默認是上面的類加載器,能夠修改擴展 ClassLoader dynamicLoader
= beanClassLoader; boolean freshResolve = false; if (!ObjectUtils.isEmpty(typesToMatch)) { //若是tempClassLoader不是空,動態類加載器設置爲tempClassLoader ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { dynamicLoader = tempClassLoader; freshResolve = true; if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class<?> typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } } } String className = mbd.getBeanClassName(); if (className != null) { Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) { //若是evaluateBeanDefinitionString if (evaluated instanceof Class) { return (Class<?>) evaluated; } else if (evaluated instanceof String) { className = (String) evaluated; freshResolve = true; } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } if (freshResolve) { //使用dynamicLoader加載class而且不和RootBeanDefinition關聯,目前沒有用到過,後面確認用處 if (dynamicLoader != null) { try { return dynamicLoader.loadClass(className); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); } } } return ClassUtils.forName(className, dynamicLoader); } } //常規處理方式,RootBeanDefinition使用默認類加載器而且關聯到RootBeanDefinition return mbd.resolveBeanClass(beanClassLoader); }

Spring Bean實例化階段

AbstractAutowireCapableBeanFactory#createBeanInstance方法處理Spring Bean實例化,給指定beanName建立一個新的實例,前後使用工廠方法、構造器自動注入、簡單實例化方式建立,具體代碼以下所示: 

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //使用RootBeanDefinition加載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()); }
     //配置lamda方式實例化Bean Supplier
<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); }
     //若是是工廠方式,用工廠方式實例化對象
if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } //若是某個RootBeanDefinition已經實例化過再次實例化,直接使用上次配置,不須要再決策 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() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //獲取合適構造器 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } //使用無參構造器實例化對象 return instantiateBean(beanName, mbd); }

Spring Bean實例化前階段

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation方法提供一個擴展方式可讓Spring Bean在實例化前作一些擴展,好比一些RPC場景,能夠在這裏生成RPC接口代理類,不執行實例化邏輯,具體代碼以下所示:

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            //若是有InstantiationAwareBeanPostProcessors,調用applyBeanPostProcessorsBeforeInstantiation方法獲取對象
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         //調用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法建立對象 Object result
= ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }

Spring Bean實例化後階段

AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法是Spring提供的第一個Spring Bean實例化後擴展,實現MergedBeanDefinitionPostProcessor接口便可進行擴展,具體代碼以下所示:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}

Spring提供的第二個實例化後擴展是InstantiationAwareBeanPostProcessor,在方法AbstractAutowireCapableBeanFactory#populateBean裏有一段代碼處理這個擴展,具體代碼以下所示:

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }
}

Spring Bean賦值前階段

Spring Bean賦值前提供擴展是InstantiationAwareBeanPostProcessor#postProcessProperties和InstantiationAwareBeanPostProcessor#postProcessPropertyValues,在方法AbstractAutowireCapableBeanFactory#populateBean裏有一段代碼處理這兩個擴展,具體代碼以下所示:

if (hasInstAwareBpps) {
   if (pvs == null) {
      pvs = mbd.getPropertyValues();
   }
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            if (filteredPds == null) {
               filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               return;
            }
         }
         pvs = pvsToUse;
      }
   }
}

Spring Bean賦值階段

Spring Bean賦值階段代碼以下所示:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
   if (pvs.isEmpty()) {
      return;
   }

   if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
   }

   MutablePropertyValues mpvs = null;
   List<PropertyValue> original;

   if (pvs instanceof MutablePropertyValues) {
      mpvs = (MutablePropertyValues) pvs;
      if (mpvs.isConverted()) {
         // Shortcut: use the pre-converted values as-is.
         try {
            bw.setPropertyValues(mpvs);
            return;
         }
         catch (BeansException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
      }
      original = mpvs.getPropertyValueList();
   }
   else {
      original = Arrays.asList(pvs.getPropertyValues());
   }

   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   // Create a deep copy, resolving any references for values.
   List<PropertyValue> deepCopy = new ArrayList<>(original.size());
   boolean resolveNecessary = false;
   for (PropertyValue pv : original) {
      if (pv.isConverted()) {
         deepCopy.add(pv);
      }
      else {
         String propertyName = pv.getName();
         Object originalValue = pv.getValue();
         if (originalValue == AutowiredPropertyMarker.INSTANCE) {
            Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
            if (writeMethod == null) {
               throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
            }
            originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
         }
         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
         Object convertedValue = resolvedValue;
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }
         // Possibly store converted value in merged bean definition,
         // in order to avoid re-conversion for every created bean instance.
         if (resolvedValue == originalValue) {
            if (convertible) {
               pv.setConvertedValue(convertedValue);
            }
            deepCopy.add(pv);
         }
         else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
            pv.setConvertedValue(convertedValue);
            deepCopy.add(pv);
         }
         else {
            resolveNecessary = true;
            deepCopy.add(new PropertyValue(pv, convertedValue));
         }
      }
   }
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }

   // Set our (possibly massaged) deep copy.
   try {
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   }
   catch (BeansException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
   }
}

Spring Bean初始化階段

Spring Bean初始化階段能夠細分爲如下幾個階段:

  • Spring Bean Aware接口回調階段
  • Spring Bean初始化前階段
  • Spring Bean初始化階段
  • Spring Bean初始化後階段

Spring Bean初始化代碼以下所示:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//Spring Bean Aware接口回調
if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean;
//Spring Bean初始化前階段
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
//Spring Bean初始化階段
try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); }
//Spring Bean初始化後階段
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

Spring Bean Aware接口回調階段

invokeAwareMethods具體代碼以下所示:

    private void invokeAwareMethods(final String beanName, final 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);
            }
        }
    }

Spring Bean初始化前階段

applyBeanPostProcessorsBeforeInitialization具體代碼以下所示:

這個方法會調用BeanPostProcessor#postProcessBeforeInitialization方法。

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

Spring Bean初始化階段

invokeInitMethods具體代碼以下所示:

    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
     //處理InitializingBean#afterPropertiesSet方法初始化Bean
        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); } } }

Spring Bean初始化後階段

applyBeanPostProcessorsAfterInitialization具體代碼以下所示:

這個方法回調用BeanPostProcessor#postProcessAfterInitialization方法。

    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

Spring Bean銷燬階段

Spring Bean銷燬階段能夠細分爲如下幾個階段:

  • Spring Bean銷燬前階段
  • Spring Bean銷燬階段

Spring Bean在初始化後會調用registerDisposableBeanIfNecessary方法註冊到disposableBeans,方便後續銷燬。

    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()) {
                //註冊DisposableBeanAdapter,後續銷燬時用
                registerDisposableBean(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
            else {
                //若是不是單例並且不是原生,好比servlet裏context、request等做用域,在必定階段觸發scope銷燬操做會銷燬Bean
                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, getBeanPostProcessors(), acc));
            }
        }
    }
    public void destroy() {
     //Spring銷燬前階段,調動DestructionAwareBeanPostProcessor#postProcessBeforeDestruction方法
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } }
     //調用DisposableBean#destroy方法
if (this.invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'"); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); } } catch (Throwable ex) { String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'"; if (logger.isDebugEnabled()) { logger.warn(msg, ex); } else { logger.warn(msg + ": " + ex); } } }
     //調用自定義銷燬函數
if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }

Spring Bean垃圾收集階段

Spring Bean在Spring應用上下文關閉後觸發GC會觸發Spring Bean垃圾收集。

相關文章
相關標籤/搜索