国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring: Bean的創(chuàng)建原理解析

這篇具有很好參考價(jià)值的文章主要介紹了Spring: Bean的創(chuàng)建原理解析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


一、Spring創(chuàng)建Bean流程

Spring: Bean的創(chuàng)建原理解析
1.讀取Bean的定義信息
通過BeanDefinitionReader這個(gè)接口解析xml配置、配置類或其他的一些方式定義的類,得到BeanDefinition(Bean定義信息)

2.實(shí)例化Bean
通過BeanPostProcessor這個(gè)接口(增強(qiáng)器)可以對(duì)我們的BeanDefinition進(jìn)行一些修改,然后BeanFactory通過反射實(shí)例化Bean對(duì)象,但是此時(shí)的Bean對(duì)象還沒有進(jìn)行初始化,沒有填充屬性等操作。

3.初始化Bean
(1)自定義屬性賦值是用 set 方法賦值(populateBean())
(2)容器對(duì)象的屬性賦值是用實(shí)現(xiàn)Aware接口的方式來賦值(invokeAwareMethods()),如BeanNameAware
(3)調(diào)用BeanPostProcessor的前置處理方法
(4)調(diào)用init初始化方法:init-method
(5)調(diào)用BeanPostProcessor的后置處理方法(AOP在這里實(shí)現(xiàn))
(6)獲得一個(gè)完整的對(duì)象,并將對(duì)象放入map中(通過Context.getBean()可以獲取到Bean對(duì)象并使用)

4.銷毀Bean
Spring容器關(guān)閉時(shí)會(huì)調(diào)用DisposableBean的Destory()方法
如果你在這個(gè)Bean中配置了destory-method屬性,會(huì)自動(dòng)調(diào)用指定的銷毀方法

二、Bean的整體創(chuàng)建流程

Spring: Bean的創(chuàng)建原理解析

  • 1.利用該類的構(gòu)造方法來實(shí)例化得到一個(gè)對(duì)象(但是如果一個(gè)類中有多個(gè)構(gòu)造方法, Spring則會(huì)進(jìn)行選擇,這個(gè)叫做推斷構(gòu)造方法,下文在詳細(xì)介紹)
  • 2.得到一個(gè)對(duì)象后,Spring會(huì)判斷該對(duì)象中是否存在被@Autowired注解了的屬 性,把這些屬性找出來并由Spring進(jìn)行賦值(依賴注入)
  • 3.依賴注入后,Spring會(huì)判斷該對(duì)象是否實(shí)現(xiàn)了BeanNameAware接口、 BeanClassLoaderAware接口、BeanFactoryAware接口,如果實(shí)現(xiàn)了,就表示當(dāng)前 對(duì)象必須實(shí)現(xiàn)該接口中所定義的setBeanName()、setBeanClassLoader()、 setBeanFactory()方法,那Spring就會(huì)調(diào)用這些方法并傳入相應(yīng)的參數(shù)
  • 4.Aware回調(diào)后,Spring會(huì)判斷該對(duì)象中是否存在某個(gè)方法被@PostConstruct注解 了,如果存在,Spring會(huì)調(diào)用當(dāng)前對(duì)象的此方法(初始化前),上面的代碼中初始化了一個(gè)adminUser的數(shù)據(jù)。
  • 5.緊接著,Spring會(huì)判斷該對(duì)象是否實(shí)現(xiàn)了InitializingBean接口,如果實(shí)現(xiàn)了,就 表示當(dāng)前對(duì)象必須實(shí)現(xiàn)該接口中的afterPropertiesSet()方法,那Spring就會(huì)調(diào)用當(dāng)
    前對(duì)象中的afterPropertiesSet()方法(初始化)
  • 6.最后,Spring會(huì)判斷當(dāng)前對(duì)象需不需要進(jìn)行AOP,如果不需要那么Bean就創(chuàng)建完 了,如果需要進(jìn)行AOP,則會(huì)進(jìn)行動(dòng)態(tài)代理并生成一個(gè)代理對(duì)象做為Bean(初始化 后)
    關(guān)于第6步控制臺(tái)沒辦法打出日志,因?yàn)槌跏己笊婕暗絪pring的源碼操作,但是可以通過斷點(diǎn)看一下,提一句例子中UserService是被LogAspect切面切的。

這樣,一個(gè)Bean就創(chuàng)建完了,如果當(dāng)前Bean是單例Bean,那么會(huì)把該Bean對(duì)象存入一個(gè)Map<String, Object>,Map的key為beanName,value為Bean對(duì)象。這樣下次getBean時(shí)就可 以直接從Map中拿到對(duì)應(yīng)的Bean對(duì)象了。(實(shí)際上,在Spring源碼中,這個(gè)Map就 是單例池)
如果當(dāng)前Bean是原型Bean,那么后續(xù)沒有其他動(dòng)作,不會(huì)存入一個(gè)Map,下次 getBean時(shí)會(huì)再次執(zhí)行上述創(chuàng)建過程,得到一個(gè)新的Bean對(duì)象。

三、推斷構(gòu)造方法

至此,我們清楚了Bean的創(chuàng)建流程,那如果UserService中有多個(gè)構(gòu)造函數(shù)呢?第一步還能順利的創(chuàng)建一個(gè)普通對(duì)象嗎?這里面涉及到一個(gè)概念推斷構(gòu)造方法,就是spring會(huì)去推斷用哪個(gè)構(gòu)造方法來創(chuàng)建出普通對(duì)象。

總結(jié)下:

  • 如果一個(gè)類只有一個(gè)構(gòu)造方法,那么沒得選擇,只能用這個(gè)構(gòu)造方法。但是有參的構(gòu)造方法,參數(shù)必須是spring的Bean這樣spring才能拿到進(jìn)行賦值。
  • 如果一個(gè)類存在多個(gè)構(gòu)造方法,Spring不知道如何選擇,就會(huì)看是否有無參的構(gòu) 造方法,因?yàn)闊o參構(gòu)造方法本身表示了一種默認(rèn)的構(gòu)造方法。
  • 如果都沒有構(gòu)造方法,就是用默認(rèn)的無參構(gòu)造方法來創(chuàng)建。
  • 其實(shí)多個(gè)構(gòu)造函數(shù),也可以手動(dòng)指定告訴spring用哪個(gè)構(gòu)造函數(shù)來創(chuàng)建,那就是加了@Autowired注解

四、依賴注入流程

不管是屬性注入還是構(gòu)造方法注入,能提供的信息只有兩個(gè)一個(gè)是類型OrderService ,一個(gè)是名字orderService。那到底是根據(jù)類型注入的還是根據(jù)名字注入的呢?
假設(shè)根據(jù)名字注入的那剛好有一個(gè)其他類型的Bean名字也叫orderService那注入的時(shí)候豈不是會(huì)類型不匹配異常。比如說剛好有一個(gè)OrderBaseService類但是beanName也叫orderService,如果根據(jù)名字注入的話拿到的是OrderBaseService對(duì)象顯然類型不匹配。所以注入通常是先根據(jù)類型來查找的:

  • 先根據(jù)入?yún)㈩愋驼?,如果只找到一個(gè)不用管name,那就直接用來作為入?yún)?/li>
  • 如果根據(jù)類型找到多個(gè),則再根據(jù)入?yún)⒚謥泶_定唯一
  • 最終如果沒有找到,則會(huì)報(bào)錯(cuò),無法創(chuàng)建當(dāng)前Bean對(duì)象

五、代理對(duì)象生成

代理對(duì)象通常是AOP的時(shí)候會(huì)生成代理對(duì)象還有一種就是開啟事務(wù)的時(shí)候也會(huì)生成代理對(duì)象。否則的話Bean都是直接根據(jù)構(gòu)造函數(shù)生成對(duì)象在進(jìn)行依賴注入和初始化等流程。

1.AOP代理對(duì)象生成

AOP就是進(jìn)行動(dòng)態(tài)代理,在創(chuàng)建一個(gè)Bean的過程中,Spring在最后一步會(huì)去判斷當(dāng)前正在 創(chuàng)建的這個(gè)Bean是不是需要進(jìn)行AOP,如果需要?jiǎng)t會(huì)進(jìn)行動(dòng)態(tài)代理。

如何判斷當(dāng)前Bean對(duì)象需不需要進(jìn)行AOP:

  • 1.找出所有的切面Bean
  • 2.遍歷切面中的每個(gè)方法,看是否寫了@Before、@After等注解
  • 3.如果寫了,則判斷所對(duì)應(yīng)的Pointcut是否和當(dāng)前Bean對(duì)象的類是否匹配
  • 4.如果匹配則表示當(dāng)前Bean對(duì)象有匹配的的Pointcut,表示需要進(jìn)行AOP

利用cglib進(jìn)行AOP的大致流程:

  • 1.生成代理類UserServiceProxy,代理類繼承UserService
  • 2.代理類中重寫了父類的方法,比如UserService中的test()方法
  • 3.代理類中還會(huì)有一個(gè)target屬性,該屬性的值為被代理對(duì)象(也就是通過 UserService類推斷構(gòu)造方法實(shí)例化出來的對(duì)象,進(jìn)行了依賴注入、初始化等步驟的 對(duì)象)
  • 4.代理類中的test()方法被執(zhí)行時(shí)的邏輯如下:
    • a. 執(zhí)行切面邏輯(@Before)
    • b. 調(diào)用target.test()
      當(dāng)我們從Spring容器得到UserService的Bean對(duì)象時(shí),拿到的就是UserServiceProxy所生 成的對(duì)象,也就是代理對(duì)象。
      UserService代理對(duì)象.test()—>執(zhí)行切面邏輯—>target.test(),注意target對(duì)象不是代理 對(duì)象,而是被代理對(duì)象。

2.事務(wù)代理對(duì)象生成

Spring事務(wù) 當(dāng)我們?cè)谀硞€(gè)方法上加了@Transactional注解后,就表示該方法在調(diào)用時(shí)會(huì)開啟Spring事 務(wù),而這個(gè)方法所在的類所對(duì)應(yīng)的Bean對(duì)象會(huì)是該類的代理對(duì)象。
Spring事務(wù)的代理對(duì)象執(zhí)行某個(gè)方法時(shí)的步驟:

  • 1.判斷當(dāng)前執(zhí)行的方法是否存在@Transactional注解
  • 2.如果存在,則利用事務(wù)管理器(TransactionMananger)新建一個(gè)數(shù)據(jù)庫(kù)連接,
  • 3.修改數(shù)據(jù)庫(kù)連接的autocommit為false
  • 4.執(zhí)行target.test(),執(zhí)行程序員所寫的業(yè)務(wù)邏輯代碼,也就是執(zhí)行sql
  • 5.執(zhí)行完了之后如果沒有出現(xiàn)異常,則提交,否則回滾

注意:Spring事務(wù)是否會(huì)失效的判斷標(biāo)準(zhǔn):某個(gè)加了@Transactional注解的方法被調(diào)用時(shí),要判 斷到底是不是直接被代理對(duì)象調(diào)用的,如果是則事務(wù)會(huì)生效,如果不是則失效。

總結(jié)

Spring中Bean的創(chuàng)建過程其實(shí)就是從一個(gè)普通對(duì)象蛻變成Bean的一個(gè)過程,蛻變包括依賴注入,初始化等步驟。最后在看下這個(gè)類是否有被AOP或開啟事務(wù)有的話會(huì)額外生成代理對(duì)象作為Bean。

其他

參考:https://www.jianshu.com/p/57ed586e258c
https://www.csdn.net/tags/MtjaYgxsOTU3NTMtYmxvZwO0O0OO0O0O.html文章來源地址http://www.zghlxwxcb.cn/news/detail-455097.html

到了這里,關(guān)于Spring: Bean的創(chuàng)建原理解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Spring 】執(zhí)行流程解析:了解Bean的作用域及生命周期

    【Spring 】執(zhí)行流程解析:了解Bean的作用域及生命周期

    ?哈嘍,哈嘍,大家好~ 我是你們的老朋友: 保護(hù)小周?? ? 今天給大家?guī)淼氖?Spring 項(xiàng)目的執(zhí)行流程解析? 和 Bean 對(duì)象的6 種作用域 以及 生命周期 , 本文將為大家講解,一起來看看叭~ 本期收錄于博主的專欄 :JavaEE_保護(hù)小周?的博客-CSDN博客 適用于編程初學(xué)者,感興趣

    2024年02月16日
    瀏覽(23)
  • 【Spring】(三)Spring 使用注解存儲(chǔ)和讀取 Bean對(duì)象

    【Spring】(三)Spring 使用注解存儲(chǔ)和讀取 Bean對(duì)象

    前面的文章詳細(xì)的介紹了 Spring 對(duì)象的創(chuàng)建,以及對(duì) Bean 對(duì)象的存取操作,但是通過配置文件注冊(cè) Bean 對(duì)象以及使用 ApplicationContext 或 BeanFactory 的方式獲取 Bean 對(duì)象的操作就顯得格外的復(fù)雜。因此,本文主要就是詳細(xì)介紹了一種更加簡(jiǎn)單的方式來實(shí)現(xiàn)對(duì) Bean 對(duì)象更加簡(jiǎn)單的儲(chǔ)

    2024年02月14日
    瀏覽(19)
  • 【Spring】使用注解讀取和存儲(chǔ)Bean對(duì)象

    【Spring】使用注解讀取和存儲(chǔ)Bean對(duì)象

    ?哈嘍,哈嘍,大家好~ 我是你們的老朋友: 保護(hù)小周? ?? 談起Java 圈子里的框架,最年長(zhǎng)最耀眼的莫過于 Spring 框架啦,本期給大家?guī)淼氖牵? 將對(duì)象存儲(chǔ)到 Spring 中、Bean 對(duì)象的命名規(guī)則、從Spring 中獲取bean 對(duì)象、注入的、@Autowired 與?@Resource 的區(qū)別、解決@Bean 方

    2024年02月13日
    瀏覽(23)
  • Spring中Bean對(duì)象的存儲(chǔ)與讀取

    Spring中Bean對(duì)象的存儲(chǔ)與讀取

    在項(xiàng)目的 pom.xml 中添加 Spring 支持 如何選定版本環(huán)境:打開官網(wǎng),點(diǎn)擊github圖標(biāo) jdk8最后一個(gè)Spring版本是5.3.x,Spring6.0.x最低需要jdk17 版本沖突問題Maven自己處理 version : 可以選擇帶有 RELEASE結(jié)尾或者純數(shù)字結(jié)尾,這樣的版本更穩(wěn)定 項(xiàng)目下創(chuàng)建一個(gè)main方法的啟動(dòng)類 存儲(chǔ) Bean 之前

    2024年01月24日
    瀏覽(22)
  • Spring(二):更簡(jiǎn)單的存儲(chǔ)與讀取 Bean

    Spring(二):更簡(jiǎn)單的存儲(chǔ)與讀取 Bean

    通過上一章的Spring,我們基本實(shí)現(xiàn)了Spring 的讀取與存儲(chǔ),但是在操作過程中,讀取與存儲(chǔ)并沒有那么得“簡(jiǎn)單” 一套流程還是很復(fù)雜,所以,本章來介紹更加簡(jiǎn)單得讀取與存儲(chǔ)。 在 Spring 中想要更簡(jiǎn)單的存儲(chǔ)和讀取對(duì)象的核?是使?注解,也就是我們接下來要學(xué)習(xí) Spring 中的

    2024年02月15日
    瀏覽(17)
  • Spring更簡(jiǎn)單的存儲(chǔ)和讀取Bean對(duì)象

    Spring更簡(jiǎn)單的存儲(chǔ)和讀取Bean對(duì)象

    目錄 1.第一個(gè)Spring項(xiàng)目 2.存儲(chǔ)Bean對(duì)象 2.1 準(zhǔn)備工作 2.2?五大類注解 2.3?方法注解@Bean 2.4 Bean對(duì)象的默認(rèn)命名規(guī)則 3. 讀取Bean對(duì)象 3.1 屬性注入 3.2 setter注入 3.3 構(gòu)造方法注入 3.4 注入異常問題 3.5 注入方式優(yōu)缺點(diǎn) 3.6 @Autowired和@Resource的區(qū)別 在學(xué)習(xí)更簡(jiǎn)單的方式來讀取和存儲(chǔ)Bean對(duì)象

    2024年02月03日
    瀏覽(24)
  • 使用Spring的五大類注解讀取和存儲(chǔ)Bean

    使用Spring的五大類注解讀取和存儲(chǔ)Bean

    目錄 1.存儲(chǔ)Bean對(duì)象的注解 1.1 五大類注解 1.2 方法注解 1.3添加注解的依賴 2.注解的使用 2.1??controller注解 2. 2Service注解 ?2.3.Resopsitory注解 2.4Component注解 2.5Configuration注解 2.6 注解之間的關(guān)系 3.方法注解 3.1 方法注解要配合類注解來使用。 3.2 重命名Bean 4.獲取Bean對(duì)象(對(duì)象裝配

    2024年02月01日
    瀏覽(24)
  • spring啟動(dòng)流程 (2) Bean實(shí)例化流程

    本文通過閱讀Spring源碼,分析Bean實(shí)例化流程。 上一篇文章已經(jīng)介紹,Bean實(shí)例化入口在AbstractApplicationContext類的finishBeanFactoryInitialization方法: 返回指定beanName的(原始)單例對(duì)象,如果沒有則創(chuàng)建一個(gè)新對(duì)象: 創(chuàng)建Bean實(shí)例、填充屬性、調(diào)用后置處理器等:

    2024年02月11日
    瀏覽(29)
  • Spring中Bean加載流程

    Spring中Bean加載流程

    BeanDefinition 1.1什么是BeanDefinition? 1.2 BeanDifinition中重要的屬性 1.3 BeanDefinition的解析 BeanFactory 2.1 什么是BeanFactory? 2.2 BeanFactory工作流程: Bean生命周期 3.1 什么是Bean生命周期? Bean生命周期是Spring中一個(gè)Bean創(chuàng)建過程和銷毀過程中所經(jīng)歷的步驟,其中Bean創(chuàng)建過程是重點(diǎn)。 3.2 核

    2024年02月09日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包