<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生命周期

          共 13726字,需瀏覽 28分鐘

           ·

          2021-05-19 02:37

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

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

            作者 |  歪頭兒在帝都 

          來(lái)源 |  urlify.cn/um6rIv

          前言

          Spring Bean生命周期是常見(jiàn)的面試題,也是日常開(kāi)發(fā)中經(jīng)常用到的技術(shù)點(diǎn),在應(yīng)用開(kāi)發(fā)中,常常需要執(zhí)行一些特殊的初始化工作,如建立數(shù)據(jù)庫(kù)連接,打開(kāi)網(wǎng)絡(luò)連接,又比如在一些業(yè)務(wù)bean里,你想拿到Spring IOC容器,又或者是想拿到一些已經(jīng)實(shí)例化的Bean。同時(shí),在服務(wù)結(jié)束時(shí),也有一些銷(xiāo)毀銷(xiāo)毀工作需要執(zhí)行。為了便于工作的設(shè)計(jì),Spring IOC提供相關(guān)接口,可以讓?xiě)?yīng)用定制Bean的初始化和銷(xiāo)毀。

          Spring Bean生命周期

          先來(lái)看一下Spring Bean生命周期流程圖,方便對(duì)照后續(xù)的源碼分析。

          Spring Bean生命周期從大的節(jié)點(diǎn)上分為4個(gè)過(guò)程:實(shí)例化、屬性賦值、初始化、銷(xiāo)毀。日常業(yè)務(wù)開(kāi)發(fā)過(guò)程中,我們應(yīng)該涉及最多的兩個(gè)點(diǎn)就是初始化和銷(xiāo)毀,比如自定義Bean實(shí)現(xiàn)InitializingBean、DisposeableBean。

          源碼分析

          Spring IOC容器初始化

          初始化從AbstractAutowireCapableBeanFactory.doCreateBean方法開(kāi)始說(shuō)起,我在對(duì)應(yīng)的代碼位置標(biāo)注了關(guān)鍵點(diǎn)

          protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
           BeanWrapper instanceWrapper = null;
           if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
           }
              
           //1. Bean實(shí)例化
           if (instanceWrapper == null) {
              instanceWrapper = this.createBeanInstance(beanName, mbd, args);
           }

           Object bean = instanceWrapper.getWrappedInstance();
           Class<?> beanType = instanceWrapper.getWrappedClass();
           if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
           }

           synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
             try {
              this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
             } catch (Throwable var17) {
              throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
             }

             mbd.postProcessed = true;
            }
           }

           boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
           if (earlySingletonExposure) {
            this.addSingletonFactory(beanName, () -> {
             return this.getEarlyBeanReference(beanName, mbd, bean);
            });
           }

           Object exposedObject = bean;

           try {
               //2.屬性賦值
                 this.populateBean(beanName, mbd, instanceWrapper);
               //3.初始化
               exposedObject = this.initializeBean(beanName, exposedObject, mbd);
           } catch (Throwable var18) {
               if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
            throw (BeanCreationException)var18;
               }

               throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
           }

           if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
             if (exposedObject == bean) {
              exposedObject = earlySingletonReference;
             } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
              String[] dependentBeans = this.getDependentBeans(beanName);
              Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
              String[] var12 = dependentBeans;
              int var13 = dependentBeans.length;

              for(int var14 = 0; var14 < var13; ++var14) {
               String dependentBean = var12[var14];
               if (!this.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.");
              }
             }
            }
           }

           try {
               //4.銷(xiāo)毀 - 注冊(cè)回調(diào)接口
               this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
               return exposedObject;
           } catch (BeanDefinitionValidationException var16) {
               throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
           }
          }

          為了保持代碼片段精簡(jiǎn),我刪掉了其中的logger代碼。


          從以上代碼片段里可以看到我們上面總結(jié)的Spring生命后期4個(gè)關(guān)鍵點(diǎn)都有體現(xiàn),我們著重分析初始化和銷(xiāo)毀流程。

          AbstractAutowireCapableBeanFactory.initializeBean

          protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
           //1.檢查Aware相關(guān)接口并設(shè)置相關(guān)依賴
              //BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
           if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
             this.invokeAwareMethods(beanName, bean);
             return null;
            }, this.getAccessControlContext());
           } else {
            this.invokeAwareMethods(beanName, bean);
           }

              //2.BeanPostProcessor前置處理
           Object wrappedBean = bean;
           if (mbd == null || !mbd.isSynthetic()) {
               //BeanPostProcessor接口的postProcessBeforeInitialization回調(diào)
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
           }
              
           //3.若實(shí)現(xiàn)InitializingBean接口,則調(diào)用afterPropertiesSet()
           //4.若配置自定義的init-method(), 則執(zhí)行。
           try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
           } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
           }

              //5.BeanPostProcessor后置處理
           if (mbd == null || !mbd.isSynthetic()) {
               //BeanPostProcessor接口的postProcessAfterInitialization回調(diào)
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
           }

           return wrappedBean;
          }

          AbstractAutowireCapableBeanFactory.invokeAwareMethods
          invokeAwareMethod就是調(diào)用一系列Aware結(jié)尾的接口,比如
          BeanNameAware、ApplicationContextAware、BeanFactoryAware。

          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 = this.getBeanClassLoader();
                     if (bcl != null) {
                         ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                     }
                 }

                 if (bean instanceof BeanFactoryAware) {
                     ((BeanFactoryAware)bean).setBeanFactory(this);
                 }
             }
           }

          AbstractAutowireCapableBeanFactory.invokeInitMethods
          invokeinitMethods就是調(diào)用InitializingBean接口的afterPropertiesSet,并且檢查自定義init-method。

          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 (System.getSecurityManager() != null) {
             try {
              AccessController.doPrivileged(() -> {
               ((InitializingBean)bean).afterPropertiesSet();
               return null;
              }, this.getAccessControlContext());
             } catch (PrivilegedActionException var6) {
              throw var6.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)) {
             this.invokeCustomInitMethod(beanName, bean, mbd);
            }
           }
          }

          從以上代碼片段可以看出Spring IOC容器創(chuàng)建Bean的過(guò)程, 涉及的過(guò)程包括實(shí)例化,銷(xiāo)毀,還包括BeanPostProcessor接口相關(guān)方法實(shí)現(xiàn),以上代碼片段我們分析了Spring容器初始化過(guò)程加載Bean的各種實(shí)現(xiàn),下面我們看下Spring容器銷(xiāo)毀階段。

          容器銷(xiāo)毀

          Spring容器銷(xiāo)毀過(guò)程調(diào)用鏈

          Spring在這里用了適配器模式,也就是說(shuō)最終的銷(xiāo)毀任務(wù)由DisposableBeanAdapter來(lái)完成,我們看下DisposeableBeanAdapter的結(jié)構(gòu)。

          從結(jié)構(gòu)中可以看到bean屬性類(lèi)型為Object, 也就是要銷(xiāo)毀的Bean,還有beanName屬性。

          public void destroy() {
              if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
                  Iterator var1 = this.beanPostProcessors.iterator();

                  while(var1.hasNext()) {
                      DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();
                      processor.postProcessBeforeDestruction(this.bean, this.beanName);
                  }
              }

           if (this.invokeDisposableBean) {
            try {
             if (System.getSecurityManager() != null) {
              AccessController.doPrivileged(() -> {
               ((DisposableBean)this.bean).destroy();
               return null;
              }, this.acc);
             } else {
              ((DisposableBean)this.bean).destroy();
             }
            } catch (Throwable var3) {
             
            }
           }

           if (this.destroyMethod != null) {
            this.invokeCustomDestroyMethod(this.destroyMethod);
           } else if (this.destroyMethodName != null) {
            Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);
            if (methodToInvoke != null) {
             this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
            }
           }
          }


          總結(jié)

          Spring Bean生命周期分為4個(gè)階段和多個(gè)擴(kuò)展點(diǎn),擴(kuò)展點(diǎn)又分為影響多個(gè)Bean和單個(gè)Bean。
          4個(gè)階段:實(shí)例化、屬性賦值、初始化、銷(xiāo)毀。
          擴(kuò)展點(diǎn)
          影響多個(gè)Bean

          • BeanPostProcessor

          • InstantiationAwareBeanPostProcessor


          影響單個(gè)Bean

          • BeanNameAware

          • BeanFactoryAware

          • BeanClassLoaderAware

          • ApplicationContextAware


          Spring生命周期中兩個(gè)關(guān)鍵的接口:InitializingBean, DisposableBean。






          粉絲福利:Java從入門(mén)到入土學(xué)習(xí)路線圖

          ??????

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


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

          瀏覽 66
          點(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>
                  亚洲欧美精品suv | 手机免费观看AV | 国产精品久久久久久久牛牛 | 国产重口老太太伦视频 | 看黄色毛片|