SpringBoot原理之二_ApplicationContext

IMchg發表於2020-12-22

https://www.jianshu.com/p/4c0723615a52
我擦,這個情景好相似,根本就是一毛一樣

先看個大概吧,多多瞭解,有個大概模糊感受即可。

以下教程需要按順序閱讀

大力推薦:https://janus.blog.csdn.net/article/details/54343570
大力推薦:https://blog.csdn.net/u012385190/article/details/81368172
結合原始碼:https://blog.csdn.net/gloomy_114/article/details/70143119
補充:https://www.cnblogs.com/jieerma666/p/10805966.html
補充:https://www.cnblogs.com/chenbenbuyi/p/8166304.html
補充:https://blog.csdn.net/qq_39632561/article/details/83070140
https://blog.csdn.net/zhanglf02/article/details/89791797
補充:https://blog.csdn.net/haohaizijhz/article/details/90674774

之所以看這個,是因為碰到兩個介面:
ApplicationContext、WebApplicationContext、ApplicationContextAware

另外,我有個問題:
關於main函式,是容器先建立,還是main函式中第一行程式碼先執行。這個問題只在IDEA開發SpringBoot時才存在,用外部Tomcat的話,壓根都沒有main函式。

ServletContext、ApplicationContext:
Servlet容器,或者說ServletContext。照有的部落格來說,Servlet容器和ServletContext不是同一個東西,ServletContext只是Servlet容器記錄屬性並向外接提供資訊的介面。這裡還是先理解為一個東西吧。

Servlet容器是Tomcat建立的,對應的就是web.xml這個檔案。

Spring容器是在Servlet容器之上的,Spring IOC容器對應的是ApplicationContext。很明顯的是,spring的配置檔案是寫在web.xml中的。

Spring IOC容器是怎麼建立的,或者說與Servlet容器怎麼聯絡起來的?Spring IOC在web.xml中配置了有兩個重要的東西:spring的配置檔案、servlet環境監聽器Listener。具體過程如下:
ApplicationContext的層次比ServletContext的層次要低,被作為一個屬性欄位記錄在ServletContext中。有兩種從ServletContext中獲取ApplicationContext的方法,在下面那個連結中有說。
web.xml中context-param配置的就是ServletContext的屬性,Spring.xml這個配置檔案也作為其中的一個屬性。
web.xml中配置了一個監聽ServletContext的監聽器,這個監聽器監聽了ServletContext中的某個事件(是啥),然後觸發方法,根據ServletContext中配置的Spring.xml路徑 ,建立ApplicationContext(理解為Spring容器吧),進行初始化,存入ServletContext。【這個監聽器可以自定義,就是建立普通Listener的方法,也可以直接使用Spring提供的】
在上面另一個連結中講了,Listener執行發生在專案完全啟動之前,比所有的Servlet都要早。而Listener本身是被Tomcat建立的,Tomcat先建立SevletContext,再根據web.xml為其屬性賦值,並建立Listener等。
另外,注意到web.xml中還有其他的Servlet存在,比如DispatcherServlet,web.xml中的這些Servlet與ApplicationContext並不是平級的,他們的層次低於ApplicationContext,這些Servlet也存在自己的ServletContext,並將ApplicationContext設定為他們的父容器。
【有個疑問啊,web.xml和spring.xml配置檔案的載入是交替進行的嗎?比如:web.xml中servlet還麼載入完,由於要跑去載入ApplicationContext,而載入ApplicationContext要根據Spring.xml,是立刻就把Spring.xml中所有Bean載入了嗎?這樣理解的話controller還在DispatcherServlet前面載入,感覺應該不是的,所謂的載入ApplicationContext,應該還沒有為其引數賦值吧,如果這樣的話,Spring.xml中的Bean又是什麼時候載入的呢?】
說起父容器,有涉及到,子容器能獲取父容器中的bean物件,父容器不能從子容器中獲取。子容器自己內部找不到就會到父容器中找bean物件。

ApplicationContext、WebApplicationContext:
Spring專門為Web做了一些東西,WebApplicationContext是繼承自ApplicationContext的介面,做了一些增強。之前講過ApplicationContext有三個實現類,用於讀取配置檔案,也就是再Listener中使用。WebApplicationContext也有兩個實現類,一個使用XML、一個使用註解。
【本地有時測試時,直接在main函式中使用ApplicationContext建立IOC容器了,這時是不需要Tomcat嗎?應該還是引入了某些類實現了Tomcat的功能吧,因為接收請求還是要最外面的ServletContext吧】

ApplicationContextAware

https://www.jianshu.com/p/4c0723615a52
https://blog.csdn.net/wang48430327/article/details/81064220

上面講了兩中從ServletContext中獲取ApplicationContext的方法。這裡給出了Spring框架提供的獲取ApplicationContext方法(猜測底層還是基於那兩種方式吧)。
當載入Spring配置檔案時,如果其中定義的Bean實現了ApplicationContextAware介面(載入配置檔案時會載入Bean嗎?),會自動呼叫被實現的setApplicationContext方法,傳入當前ApplicationContext為引數。【這裡時間沒講清楚啊,載入spring配置檔案,是】

反覆看到一個說法:
使用DispatcherServlet載入Controller、使用ContextLoaderListener載入Service、DAO。
類似的是,Spring容器管理Service、DAO,SpringMVC容器管理Controller。【這個有的人說不對,都是由Spring容器管理的】
em,先問一下:怎麼使用DispatcherServlet載入Controller、使用ContextLoaderListener載入Service、DAO?
自己使用的時候,直接要麼XML配置包掃描,要麼配置類包掃描。沒涉及這兩個啊。

使用ContextLoaderListener載入:https://blog.csdn.net/chijieyan2142/article/details/100854333

https://blog.csdn.net/java_it90/article/details/84691888

spring.xml中通過AOP配置事務,一直還沒做過

這個裡面提到,Bean初始化在application.run之前

https://www.bbsmax.com/A/ke5j2p4y5r/

bean的例項化和初始化:先例項化,後初始化。和類載入中初始化含義不一樣吧
https://brucelee.blog.csdn.net/article/details/104419869
https://blog.csdn.net/jinxin70/article/details/83796137
過程:https://blog.csdn.net/dc282614966/article/details/81480002

相關文章