真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何理解Spring框架中Bean的生命周期

如何理解Spring框架中Bean的生命周期,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項目涵蓋了網(wǎng)頁視覺設(shè)計、VI標(biāo)志設(shè)計、營銷網(wǎng)站、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式重慶網(wǎng)站建設(shè)公司、成都做手機網(wǎng)站、微商城、網(wǎng)站托管及網(wǎng)站維護、WEB系統(tǒng)開發(fā)、域名注冊、國內(nèi)外服務(wù)器租用、視頻、平面設(shè)計、SEO優(yōu)化排名。設(shè)計、前端、后端三個建站步驟的完善服務(wù)體系。一人跟蹤測試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為門簾行業(yè)客戶提供了網(wǎng)站建設(shè)服務(wù)。

 1.Bean的生命周期

關(guān)于Bean的生命周期,如果我們不談這個Spring的話,實際上很多人都會想到New,通過 New 對象的形式來實現(xiàn)對  Bean的實例化操作,而在我們不再使用 Bean 了之后,這時候我們的 Java 就會對這個指定的 Bean 來進行垃圾回收了。

但是對于Spring來說,Bean的生命周期可能就比較讓人頭疼了,畢竟 Spring 這么復(fù)雜,而且里面的對 Bean  管理的非常的有邏輯了,每一層都有每一層的步驟。

如果現(xiàn)在我們?nèi)グ俣壬厦嫒ニ阉魉械年P(guān)于Spring的Bean的生命周期,很多人會把這個解釋出來

  • 在IoC容器啟動之后,并不會馬上就實例化相應(yīng)的bean,此時容器僅僅擁有所有對象的BeanDefinition(BeanDefinition:是容器依賴某些工具加載的XML配置信息進行解析和分析,并將分析后的信息編組為相應(yīng)的BeanDefinition)。只有當(dāng)getBean()調(diào)用時才是有可能觸發(fā)Bean實例化階段的活動

而有一些內(nèi)容就不會說解釋的很透徹,比如說為什么說只有當(dāng) getBean() 調(diào)用的時候才有可能觸發(fā)Bean的實例化。

2.生命周期流程圖

2.1簡化版圖解

如何理解Spring框架中Bean的生命周期

而這圖解中,把 Spring 中 Bean 的生命周期分成了好幾個步驟,分別是:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2. 通過構(gòu)造方法實例化 Bean 對象。

  3. 通過 setter 方法設(shè)置對象的屬性。

  4. 通過Aware,也就是他的子類BeanNameAware,調(diào)用Bean的setBeanName()方法傳遞Bean的ID(XML里面注冊的ID),setBeanName方法是在bean初始化時調(diào)用的,通過這個方法可以得到BeanFactory和  Bean 在 XML 里面注冊的ID。

  5. 如果說 Bean 實現(xiàn)了 BeanFactoryAware,那么工廠調(diào)用setBeanFactory(BeanFactory var1)  傳入的參數(shù)也是自身。

  6. 把 Bean 實例傳遞給 BeanPostProcessor 中的 postProcessBeforeInitialization 前置方法。

  7. 完成 Bean 的初始化

  8. 把 Bean 實例傳遞給 BeanPostProcessor 中的 postProcessAfterInitialization 后置方法。

  9. 此時 Bean 已經(jīng)能夠正常時候,在最后的時候調(diào)用 DisposableBean 中的 destroy 方法進行銷毀處理。

而阿粉覺得如果面試官在面試的時候問到這個問題的時候,你從圖解開始入手,然后把這些都說給他之后,那么相對應(yīng)的,這現(xiàn)在這些答案,如果不繼續(xù)的深挖內(nèi)容,可能已經(jīng)就足夠了。

而接下來還要從根本上來論證阿粉所寫的內(nèi)容。

而我們對這詳細的可能有時候難以記憶,可能還是理解不深,而我們可以從四到五個方面來記憶,

  • 構(gòu)造實例化

  • 屬性賦值

  • 完成初始化

  • (前后處理)

  • 使用后銷毀

而從這五個方面來記憶,或許就能把這個圖擴展開,從而言簡意賅的回答面試官的問題。

代碼驗證

package com.yld.bean;  import org.springframework.beans.factory.BeanNameAware;  public class Person implements BeanNameAware {      private String name;      /**      * 實現(xiàn)類上的override方法      * @param s      */     @Override     public void setBeanName(String s) {         System.out.println("調(diào)用BeanNameAware中的setName賦值");     }      public Person() {     }      /**      * 屬性賦值      * @param name      */     public void setName(String name) {         System.out.println("設(shè)置對象屬性setName()..");         this.name = name;     }      /**      * Bean初始化      */     public void initBeanPerson() {         System.out.println("初始化Bean");     }      /**      * Bean方法使用:說話      */     public void speak() {         System.out.println("使用Bean的Speak方法");     }      /**      * 銷毀Bean      */     public void destroyBeanPerson() {         System.out.println("銷毀Bean");     }   }

Main方法

public static void main(String[] args) {         ClassPathXmlApplicationContext pathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");         Person person = (Person)pathXmlApplicationContext.getBean("person");         person.speak();         pathXmlApplicationContext.close();     }

運行結(jié)果展示

D:\develop\JDK8\jdk1.8.0_181\bin\java.exe "-javaagent:D:\develop\IDEA\IntelliJ IDEA 2018.1.8\lib\idea_rt.jar=63906:D:\develop\IDEA\IntelliJ IDEA 2018.1.8\bin" -Dfile.encoding=UTF-8 -classpath D:\develop\JDK8\jdk1.8.0_181\jre\lib\charsets.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\deploy.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\DNSns.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\jaccess.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\localedata.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\nashorn.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunec.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\zipfs.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\javaws.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jce.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jfr.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jfxswt.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jsse.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\management-agent.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\plugin.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\resources.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\rt.jar;D:\develop\IDEAProject\KaiYuan\target\classes;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\2.1.8.RELEASE\spring-boot-starter-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\2.1.8.RELEASE\spring-boot-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.1.9.RELEASE\spring-context-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.1.9.RELEASE\spring-aop-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.1.9.RELEASE\spring-beans-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.1.9.RELEASE\spring-expression-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.1.8.RELEASE\spring-boot-autoconfigure-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.1.8.RELEASE\spring-boot-starter-logging-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.28\jul-to-slf4j-1.7.28.jar;C:\Users\Administrator\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.1.9.RELEASE\spring-core-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.1.9.RELEASE\spring-jcl-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.28\slf4j-api-1.7.28.jar com.yld.bean.Test 16:54:58.817 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@123772c4 16:54:59.074 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [applicationContext.xml] 16:54:59.121 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'  設(shè)置對象屬性setName()..  調(diào)用BeanNameAware中的setName賦值  初始化Bean  使用Bean的Speak方法  16:54:59.232 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@123772c4, started on Sun Jun 07 16:54:58 CST 2020  銷毀Bean  Process finished with exit code 0

和大家預(yù)想的是不是一樣的呢? 在用案例回答面試官之后,我們最好還是要研究一下源碼的部分,畢竟研究清楚了,會理解的更深刻不是么?

InstantiationAwareBeanPostProcessor

這個類是繼承的 BeanPostProcessor 而這個類的作用是什么呢?源碼注釋解釋的是這樣子的:

方法一:

@Nullable     default Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {         return null;     } 應(yīng)用這個Bean處理器在目標(biāo)Bean實例化之前。返回的bean對象可能是一個代理bean的使用而不是目標(biāo),

也就是說postProcessBeforeInstantiation在bean實例化之前調(diào)用的,這是不是也是我們在面試中另外的一個面試點 AOP  的使用呢?到時候面試官讓你舉例子的時候,你直接用這個 Spring 里面的源碼給他解釋,分分鐘讓面試官對你刮目想看呀有木有。

方法二:可以看到該方法在屬性賦值方法內(nèi),但是在真正執(zhí)行賦值操作之前。其返回值為boolean。

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

大家是不是還可以這么理解,如果返回值為false的話,那么就出現(xiàn)了賦值失敗,也就是間接阻斷賦值了。

而初始化的類同樣的 BeanPostProcessor

方法一:

任何Bean之前初始化回調(diào)如初始化Bean的屬性設(shè)置后 @Nullable     default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {         return bean;     }

方法二:

應(yīng)用這個Bean后置處理程序給定新的Bean實例,任何Bean初始化后回調(diào)(如初始化Bean的屬性設(shè)置后{@code}或一個自定義的init方法)。bean已經(jīng)填充屬性值。返回的bean實例可能是原始的包裝器。

應(yīng)用這個Bean后置處理程序給定新的Bean實例,任何Bean初始化后回調(diào)(如初始化Bean的屬性設(shè)置后{@code}或一個自定義的init方法)。bean已經(jīng)填充屬性值。返回的bean實例可能是原始的包裝器。 @Nullable     default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {         return bean;     }

同樣注釋翻譯出來的意思也是很明確的,這也是阿粉為什么喜歡自己下載個插件去看注釋,畢竟源碼這個東西如果看別人理解的和自己理解的,有時候差距也是很大的。

關(guān)于如何理解Spring框架中Bean的生命周期問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。


本文名稱:如何理解Spring框架中Bean的生命周期
網(wǎng)站路徑:http://weahome.cn/article/gsicii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部