日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring5源码 - 01 BeanDefination源码分析

發布時間:2025/3/21 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring5源码 - 01 BeanDefination源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 引入
  • Bean實例化的原理
    • singleton vs prototype
    • Singleton VS Prototype 小結
  • 下文

引入

Spring 是如何生成一個Bean的?

我們先看個例子

我們有個Configuration類AppConfig ,通過ComponentScan定義了掃描com.artisan目錄下所有表了標注了注解的Bean

package com.artisan;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.artisan") public class AppConfig { }

同時com.artisan目錄下還有A.class 和 B.class , 其中B類上標注了@Component注解,A上僅僅一個普通的Java類

package com.artisan.test;import org.springframework.stereotype.Component;@Component public class B { } package com.artisan.test;public class A { }

我們啟動下Spring容器,然后嘗試去重bean容器中獲取A和B的單例對象,看看會發生什么?

package com.artisan.test;import com.artisan.AppConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class BeanLoadTest {public static void main(String[] args) {// spring容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(ac.getBean(B.class));System.out.println(ac.getBean(A.class));} }

結果顯而易見, 被標注了@Component注解的B類,成功的從bean容器中獲取到了,而A類是無法從bean容器中獲取到的 ( No qualifying bean of type ‘com.artisan.test.A’ available)。

com.artisan.test.B@28864e92 Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.artisan.test.A' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1177)at com.artisan.test.BeanLoadTest.main(BeanLoadTest.java:12)

這是為什么呢?Spring的源碼是如何實現的呢? 接下來的文章,我們逐層揭開Sping Bean的神秘面紗 …


Bean實例化的原理

我們知道普通的Java類的實例化的過程,被JVM編譯成字節碼文件以后,通過new 關鍵字實例化。

Spring bean的實例化區別于普通Java類的實例化過程,是一個相對復雜的過程。

原理如下

1. 掃描到可以受到Spring管理的Bean,將其轉化成BeanDefinition

2. BeanDefinition是個接口,其中有很多屬性可以設置,比如 scope 、lazyInit、dependson 、autoType 、關聯的是哪個類setBeanClass 等等

3. 將BeanDefinition放入到一個Map中

4. 遍歷Map ,取出BeanDefinition,根據你上一步設置的各種屬性,去做不同的操作,比如autoType 、是否懶加載等等等等,實例化Bean

5. 實例化完成以后,將實例化好的Bean放到map中 (就是spring容器),即Spring的單例池 singletonObjectsMap

這里只會創建單例模式的Bean,prototype等類型的bean不會添加到單例池中,因為prototype每次都會new一個,沒有必要去緩存。

當然了,Spring的實現是很復雜的,我們這里先對其大致的過程和原理有個初步的了解,方便后續源碼的展開


singleton vs prototype

spring容器在啟動的時候就已經將singleton的bean 緩存到 單例池中,而 prototype類型的bean ,在spring容器啟動的時候并不會被實例化,僅在調用的時候生成,且每次都一個新的對象 。

看個演示

加個斷點,
可以發現 還沒執行到ac.getBean(B.class),僅在容器啟動階段就已經實例化完成了singleton作用域的bean。


接下來我們看下prototype類型的bean

可以看到 在spring容器啟動的時候,并沒有實例化prototype類型的bean 。


Singleton VS Prototype 小結

我們看到了 Singleton VS Prototype的區別

  • 創建時機不同: singleton的bean是在容器初始化的時候創建的,而原型bean是在調用的時候創建的
  • 作用域不同: 單例singleton的bean 在容器中僅會創建一次,并且只有一個,而原型Prototype類型的bean每次調用都會初始化一個新的對象。

  • 下文

    下文我們探討對象和bean的關系

    總結

    以上是生活随笔為你收集整理的Spring5源码 - 01 BeanDefination源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。