<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Bean 的生命周期

          共 10152字,需瀏覽 21分鐘

           ·

          2021-05-05 12:12

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          76套java從入門(mén)到精通實(shí)戰(zhàn)課程分享

          簡(jiǎn)要

          Spring是一個(gè)IOC容器框架,擁有DI依賴(lài)注入(Dependency Injection),DL依賴(lài)查找(Dependency Lookup)等功能。

          關(guān)于Spring Bean的生命周期,官方并沒(méi)有找到相關(guān)文檔。

          下邊是我根據(jù)源碼分析出四個(gè)階段,做出的生命周期解讀:

          1. 注冊(cè)階段

          2. 實(shí)例化階段

          3. 初始化階段

          4. 銷(xiāo)毀階段


          注冊(cè)階段

          注冊(cè)階段主要任務(wù)是通過(guò)各種BeanDefinitionReader讀取掃描各種配置來(lái)源信息(xml文件、注解等),并轉(zhuǎn)換為BeanDefinition的過(guò)程。


          BeanDefinition可以理解為類(lèi)的定義,描述一個(gè)類(lèi)的基本情況,比較像我們注冊(cè)某些網(wǎng)站時(shí)的基本信息,比如需要填寫(xiě)姓名、住址、出生日期等。


          最終會(huì)將我們掃描到的類(lèi)整體注冊(cè)到一個(gè)DefaultListableBeanFactory的Map容器中,便于我們之后獲取使用。

          public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactoryBeanDefinitionRegistrySerializable {
           //存儲(chǔ)注冊(cè)信息的BeanDefinition
           private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
           //beanDefinitionMap的數(shù)據(jù)結(jié)構(gòu)是ConcurrentHashMap,因此不能保證順序,為了記錄注冊(cè)的順序,這里使用了ArrayList類(lèi)型beanDefinitionNames用來(lái)記錄注冊(cè)順序
           private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
           
           //省略部分代碼.......
           @Override
           public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
            //省略判斷代碼.......
            // Still in startup registration phase
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
           }
          }



          實(shí)例化階段

          在實(shí)例化階段,Spring主要將BeanDefinition轉(zhuǎn)換為實(shí)例Bean,并放在包裝類(lèi)BeanWrapper中。


          無(wú)論是否設(shè)置Bean的懶加載方式,最后都會(huì)通過(guò)AbstractBeanFactory.getBean()方法進(jìn)行實(shí)例化,并進(jìn)入到AbstractAutowireCapableBeanFactory.createBean()方法。

          public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
           //省略部分代碼......
           @Nullable
           protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
             // Make sure bean class is actually resolved at this point.
             if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
              Class<?> targetType = determineTargetType(beanName, mbd);
              if (targetType != null) {
               //實(shí)例化前處理器
               bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
               if (bean != null) {
                //實(shí)例化后處理器
                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
               }
              }
             }
             mbd.beforeInstantiationResolved = (bean != null);
            }
            return bean;
           }
           //省略部分代碼......
          }


          在實(shí)例化階段AbstractAutowireCapableBeanFactory.createBeanInstance()完成Bean的創(chuàng)建,并放到BeanWrapper中。


          初始化階段

          初始化階段主要是在返回Bean之前做一些處理,主要由AbstractAutowireCapableBeanFactory.initializeBean()方法實(shí)現(xiàn)。


          public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
           //省略部分代碼......
           //真正創(chuàng)建Bean的方法
           protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
             throws BeanCreationException 
          {

            //省略部分代碼......
            // Initialize the bean instance.
            //Bean對(duì)象的初始化,依賴(lài)注入在此觸發(fā)
            //這個(gè)exposedObject在初始化完成之后返回作為依賴(lài)注入完成后的Bean
            Object exposedObject = bean;
            try {
             //將Bean實(shí)例對(duì)象封裝,并且Bean定義中配置的屬性值賦值給實(shí)例對(duì)象
             populateBean(beanName, mbd, instanceWrapper);
             //初始化Bean對(duì)象
             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);
             }
            }
            //省略部分代碼......
            return exposedObject;
           }
           
           //初始容器創(chuàng)建的Bean實(shí)例對(duì)象,為其添加BeanPostProcessor后置處理器
           protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            //JDK的安全機(jī)制驗(yàn)證權(quán)限
            if (System.getSecurityManager() != null) {
             //實(shí)現(xiàn)PrivilegedAction接口的匿名內(nèi)部類(lèi)
             AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
              invokeAwareMethods(beanName, bean);
              return null;
             }, getAccessControlContext());
            }
            else {
             //為Bean實(shí)例對(duì)象包裝相關(guān)屬性,如名稱(chēng),類(lèi)加載器,所屬容器等信息
             invokeAwareMethods(beanName, bean);
            }

            Object wrappedBean = bean;
            //對(duì)BeanPostProcessor后置處理器的postProcessBeforeInitialization
            //回調(diào)方法的調(diào)用,為Bean實(shí)例初始化前做一些處理
            if (mbd == null || !mbd.isSynthetic()) {
             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }

            //調(diào)用Bean實(shí)例對(duì)象初始化的方法,這個(gè)初始化方法是在Spring Bean定義配置
            //文件中通過(guò)init-method屬性指定的
            try {
             invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
             throw new BeanCreationException(
               (mbd != null ? mbd.getResourceDescription() : null),
               beanName, "Invocation of init method failed", ex);
            }
            //對(duì)BeanPostProcessor后置處理器的postProcessAfterInitialization
            //回調(diào)方法的調(diào)用,為Bean實(shí)例初始化之后做一些處理
            if (mbd == null || !mbd.isSynthetic()) {
             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }

            return wrappedBean;
           }
           //省略部分代碼......
          }


          銷(xiāo)毀階段

          一般是在ApplicationContext關(guān)閉的時(shí)候調(diào)用,也就是AbstractApplicationContext.close() 方法。


          在注冊(cè)的時(shí)候Spring通過(guò)適配器模式包裝了一個(gè)類(lèi)DisposableBeanAdapter,在銷(xiāo)毀階段的時(shí)候會(huì)獲得這個(gè)類(lèi),進(jìn)而調(diào)用到DisposableBeanAdapter.destroy()方法:

          class DisposableBeanAdapter implements DisposableBeanRunnableSerializable {
           //省略部分代碼......
           @Override
           public void destroy() {
            if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
             for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
              processor.postProcessBeforeDestruction(this.bean, this.beanName);
             }
            }

            if (this.invokeDisposableBean) {
             if (logger.isDebugEnabled()) {
              logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
             }
             try {
              if (System.getSecurityManager() != null) {
               AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                ((DisposableBean) bean).destroy();
                return null;
               }, acc);
              }
              else {
               ((DisposableBean) 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 methodToCall = determineDestroyMethod(this.destroyMethodName);
             if (methodToCall != null) {
              invokeCustomDestroyMethod(methodToCall);
             }
            }
           }
           //省略部分代碼......
          }


          銷(xiāo)毀階段主要包括三個(gè)銷(xiāo)毀途徑,按照?qǐng)?zhí)行順序:


          1. @PreDestroy注解,主要通過(guò)DestructionAwareBeanPostProcessor實(shí)現(xiàn)

          2. 實(shí)現(xiàn)DisposableBean接口,主要通過(guò)DisposableBean.destroy()實(shí)現(xiàn)

          3. 自定義銷(xiāo)毀方 DisposableBeanAdapter.invokeCustomDestroyMethod()實(shí)現(xiàn)



          ————————————————

          版權(quán)聲明:本文為CSDN博主「武當(dāng)梯云縱」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

          原文鏈接:https://blog.csdn.net/jeffYang1993/article/details/116153287




          鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

          ??????

          ??長(zhǎng)按上方微信二維碼 2 秒





          感謝點(diǎn)贊支持下哈 

          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  小早川怜子无码 | 成人高清免费观看MV | 东京热成人小说 | 日韩人妻丰满无码区A片 | 麻豆成人免费视频 |