中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中Spring源碼分析

發布時間:2022-05-30 16:25:21 來源:億速云 閱讀:119 作者:iii 欄目:大數據

這篇文章主要介紹了java中Spring源碼分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇java中Spring源碼分析文章都會有所收獲,下面我們一起來看看吧。

源碼分析

1.前期準備

/**
* spring debug
* @author huangfu
*/
public class SpringDebug {
public static void main(String[] args) {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringDebugConfig.class);
}
}
     

上面這一行代碼我估計使用過Spring的人都特別熟悉,如果不熟悉,那我勸你先學會使用,再去深究一些源碼的底層邏輯!

下面我們看一下,他究竟是如何一步一步的實例化bean,接管bean,然后執行各種生命周期類的!我們先不妨猜測一下,spring再讀取這些bean的時候,關于bean的信息一定是存放在了某一個實體上,那么這個實體是什么呢?這個類就是BeanDefinition那么他存儲了什么東西呢?我們看一下它的子類AbstractBeanDefinition

java中Spring源碼分析        

里面定義這類似與這樣的屬性值,當然作者做截取了少數屬性,它里面的屬性遠遠比這多得多,它的目的就是bean實例化的時候,需要的數據不需要再通過自己去反射獲取,而是再Spring初始化的時候全部讀取,需要的時候從這里面拿就行,了解了bd的概念之后,我們是否疑惑?他讀取之后存放在哪里呢?答案是存放再beanFactory里面,所以Spring初始化的時候肯定會先實現一個bean工廠!進入到AnnotationConfigApplicationContext里面,你會發下并沒有初始化,在那初始化呢?眾所周知,一個類再初始化的時候會先加載父類的構造函數,所以我們需要去看一下它的父類GenericApplicationContext:

public GenericApplicationContext() {
   //初始化bean的工廠
   this.beanFactory = new DefaultListableBeanFactory();
}
     

果然不出我所料,它再父類里面創建了bean工廠,工廠有了,我們繼續回到AnnotationConfigApplicationContext里面往下看:發現它調用了一個this(),說明它調用了自己的空構造方法,所以,我們進入看一下:

public AnnotationConfigApplicationContext() {
   //初始化讀取器
   this.reader = new AnnotatedBeanDefinitionReader(this);
   //初始化掃描器
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}
   

「至此我們就可以看對照上面那幅圖:初始化的時候bean工廠有了」

java中Spring源碼分析        

「然后再自己的空構造方法里面有初始化了讀取器!」

java中Spring源碼分析        

那我們繼續回到AnnotationConfigApplicationContext構造方法里面:

   /**
* 創建一個新的AnnotationConfigApplicationContext,從給定的帶注釋的類派生bean定義
* 并自動刷新上下文。
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//讀取Spring內置的幾個的class文件轉換為bd  然后初始化bean工廠
this();
//這一步就是將配置類Config進行了注冊并解析bd
register(annotatedClasses);
//這一步是核心,Spring的理解全在這一步,這一步理解了也就可以說將Spring理解了70%
//內部做一系列的操作如調用bean工廠的后置處理器   實例化類  調用 后置處理器的前置處理   初始化類  調用后置處理器的后置處理 注冊事件監聽等操作
//完成一個類從class文件變為bean的生命周期
refresh();
}
     

下一步是調用register方法,干什么呢?試想一下,有時候我們的自動掃描配置是通過注解@ComponentScan("com.service")來配置的,這個類一般在哪?對了,一般實在配置類中的!

@Configuration
@ComponentScan("com.service")
public class SpringDebugConfig {}
     

為了能夠知道,我們要掃描那些包下的類,我們就必須先去解析配置類的BeanDefinition,這樣才能獲取后續咱們要解析的包,當然這個方法不光解析了掃描的包,還解析了其他東西,本文不做講解!     

2.核心功能

好了,再往下走我們就知道了我們即將要掃描那些包下的類,讓他變成bean,那么我們繼續向下走,走到refresh();這個方法不得了他是整個Springbean初始化的核心方法,了解了它也就能夠了解Spring的實例化,回調等一些列的問題,我們進去看看:

進來之后,我們一個方法一個方法的分析做了什么功能,首先是:     

1). prepareRefresh();
?      

這里是做刷新bean工廠前的一系列賦值操作,主要是為前面創建的Spring工廠很多的屬性都是空的,這個方式是為他做一些列的初始化值的操作!

?             
2). obtainFreshBeanFactory()
?      

告訴子類刷新內部bean工廠  檢測bean工廠是否存在 判斷當前的bean工廠是否只刷新過一次,多次報錯,返回當前使用的bean工廠,當該步驟為xml時 會新建一個新的工廠并返回

?             
3). prepareBeanFactory(beanFactory);
?      

這里是初始化Spring的bean容器,向beanFactory內部注冊一些自己本身內置的Bean后置處理器也就是通常說的BeanPostProcessor,這個方法其實也是再初始化工廠!

?             
4). postProcessBeanFactory(beanFactory);
?      

允許在上下文子類中對bean工廠進行后處理,作用是在BeanFactory準備工作完成后做一些定制化的處理! 但是注意,你點進去是空方法,空方法以為著什么?意味著Spring的開發者希望調用者自定義擴展時使用!

?             
5). invokeBeanFactoryPostProcessors(beanFactory);
?      

其實相信看名字,大部分讀者都能夠猜出,他的目的是掃描非配置類的bd注冊到工廠里面,掃描完成之后,開始執行所有的BeanFactoryPostProcessors,這里出現了第一個擴展點,自定義實現BeanFactoryPostProcessors的時候,他的回調時機是在Spring讀取了全部的BeanDefinition之后調用的,具體的使用方法讀者自行百度!

?             
6). registerBeanPostProcessors(beanFactory);
?      

這里是注冊bean的后置處理器 也就是  beanPostProcessor 的實現 還有自己內置的處理器  注意這里并沒有調用該處理器,只是將胡處理器注冊進來bean工廠! 不知道大家使用過beanPostProcessor接口這個擴展點嗎?他就是再這個方法里面被注冊到Spring工廠里面的,當然注意一下,他只是注冊進去了,并沒有執行!記住并沒有執行!

?            
7). initMessageSource();
?      

怎么說呢,這個方法作者并不準備深究,因為他和本篇文章的意圖相違背,他的目的是做一個國際化操作也就是 i18n的資源初始化

?             
8).initApplicationEventMulticaster();
?      

Spring為我們提供了對于事件編程的封裝,一般來說事件分為三個角色,事件廣播器(發布事件),事件監聽器(監聽事件),事件源(具體的事件信息)三個角色,這個方法的目的就是初始化事件的廣播器!

?             
9). onRefresh();
?      

這里又是一個擴展點,內部的方法為空,Spring并沒有實現它,供調用者實現!

?             
10). registerListeners();
?      

注冊Spring的事件監聽器,上面已經說過了,這里是初始化并且注冊事件監聽器

?             
11). finishBeanFactoryInitialization(beanFactory);
?      

這個方法是一個重點,他是為了實例化所有剩余的(非延遲初始化)單例。我們所說的bean的實例化,注入,解決循環依賴,回調beanPostProcessor等操作都是再這里實現的!

?        
12). finishRefresh();
?      

最后一步:發布相應的事件。Spring內置的事件

?        

關于“java中Spring源碼分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“java中Spring源碼分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福安市| 武冈市| 盐边县| 苏州市| 内丘县| 乌兰察布市| 黔西县| 东乡| 芦山县| 永靖县| 祁门县| 通江县| 武乡县| 丽江市| 威信县| 西昌市| 呼图壁县| 湘乡市| 雷州市| 开阳县| 咸阳市| 安国市| 永仁县| 浦北县| 平武县| 扬中市| 门头沟区| 乃东县| 荔波县| 双峰县| 福州市| 宁夏| 徐水县| 密云县| 延安市| 闽清县| 宁强县| 灵丘县| 佛冈县| 永平县| 南木林县|