SpringBoot詳細(xì)講解如何創(chuàng)建及刷新Spring容器bean
- 參考視頻:https://www.bilibili.com/video/BV1Bq4y1Q7GZ?p=6
- 通過(guò)視頻的學(xué)習(xí)和自身的理解整理出的筆記。
一、前期準(zhǔn)備
1.1 創(chuàng)建工程
創(chuàng)建springboot項(xiàng)目,springboot版本為2.5.0,引入spring-boot-starter-web依賴,pom文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.2 創(chuàng)建Controller
創(chuàng)建一個(gè)簡(jiǎn)單的Controller用于測(cè)試
@RestController public class HelloController { public void helloController() { System.out.println("創(chuàng)建了"); } @RequestMapping("hello") public String hello() { return "hello"; } }
二、探究過(guò)程
2.1 啟動(dòng)類
項(xiàng)目的運(yùn)行只需要啟動(dòng)類中一行簡(jiǎn)單的代碼,spring容器的創(chuàng)建就是通過(guò)SpringApplication.run(SpringbootApplication.class, args)
這一行代碼實(shí)現(xiàn)的。
其實(shí)就是調(diào)用了靜態(tài)的run方法,傳入了啟動(dòng)類的字節(jié)碼對(duì)象。
2.2 SpringApplication
?? run()
方法
又調(diào)用了另一個(gè)run方法。
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class[]{primarySource}, args); }
?? run()
方法
方法的返回值類型為ConfigurableApplicationContext
,ApplicationContext
就是Spring的容器。
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); }
我們來(lái)看看ConfigurableApplicationContext
繼承結(jié)構(gòu)
ConfigurableApplicationContext
接口繼承了ApplicationContext
接口
下面我們通過(guò)debug進(jìn)入run()方法中看看
?? run()
方法
?? createApplicationContext()
方法
容器工廠傳入webApplication的類型,這個(gè)類型為Servlet應(yīng)用。
Springboot可以做響應(yīng)式的Web開(kāi)發(fā),這時(shí)webApplication的類型的類型就不是Servlet。
2.3 ApplicationContextFactory
這里是一個(gè)lambda表達(dá)式的寫(xiě)法,根據(jù)webApplicationType的類型返回對(duì)應(yīng)的容器對(duì)象。
通過(guò)繼承關(guān)系圖可以看出,它的確是ApplicationContext
2.4 SpringApplication
?? run()
方法,容器刷新前
看完了createApplicationContext()
的過(guò)程,我們?cè)俅位氐?code>run()方法中,此時(shí)context已經(jīng)創(chuàng)建完成。
我們觀察一下context中都有些什么:
其中包含了bean工廠,bean工廠里有beanDefinitionNames和beanDefinitionMap。(與之前看的spring源碼一樣)
不過(guò)這里都是spring容器內(nèi)置的beanDefinition對(duì)象,沒(méi)有我們自定義的helloController
,說(shuō)明現(xiàn)在的容器還沒(méi)有刷新。
我們現(xiàn)在獲取不到HelloController的bean對(duì)象,當(dāng)我們能獲取到這個(gè)對(duì)象時(shí),就說(shuō)明容器刷新了。
?? run()
方法,容器刷新后
繼續(xù)往下運(yùn)行,我們發(fā)現(xiàn)這行代碼執(zhí)行了好久,根據(jù)方法名稱也可以看出它的功能就是刷新容器。
刷新后我們成功的獲取到了bean對(duì)象。
此時(shí)beanDefinitionMap中包含了138個(gè)對(duì)象,刷新之前只包含5個(gè)。我們可以在里面找到helloController(Hello的H變成了小寫(xiě))
?? refreshContext()
方法
下面我們看看refreshContext()
方法,其中調(diào)用了refresh()
方法。
?? refresh()
方法
refreshContext()
方法中refresh(context)
傳入了容器對(duì)象,在這里調(diào)用了這個(gè)容器對(duì)象的refresh()
方法。
后面暫時(shí)不往下看了。
2.5 結(jié)論
在啟動(dòng)類中調(diào)用SpringApplication的run方法時(shí)會(huì)根據(jù)容器的類型創(chuàng)建不同的容器對(duì)象,并調(diào)用容器的refresh方法。
到此這篇關(guān)于SpringBoot詳細(xì)講解如何創(chuàng)建及刷新Spring容器bean的文章就介紹到這了,更多相關(guān)SpringBoot Spring容器bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring超詳細(xì)講解創(chuàng)建BeanDefinition流程
- Spring-Bean創(chuàng)建對(duì)象的步驟方式詳解
- Spring創(chuàng)建Bean的6種方式詳解
- Spring BPP中如何優(yōu)雅的創(chuàng)建動(dòng)態(tài)代理Bean詳解
- Spring工廠方法創(chuàng)建(實(shí)例化)bean實(shí)例代碼
- 詳解Spring Boot 使用Java代碼創(chuàng)建Bean并注冊(cè)到Spring中
- Spring創(chuàng)建Bean完成后執(zhí)行指定代碼的幾種實(shí)現(xiàn)方式
相關(guān)文章
Java中ClassLoader類加載學(xué)習(xí)總結(jié)
本篇文章主要給大家講述了Java中ClassLoader類加載的原理以及用法總結(jié),一起學(xué)習(xí)下。2017-12-12如何利用rabbitMq的死信隊(duì)列實(shí)現(xiàn)延時(shí)消息
這篇文章主要介紹了如何利用rabbitMq的死信隊(duì)列實(shí)現(xiàn)延時(shí)消息問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01如何在Spring中使用編碼方式動(dòng)態(tài)配置Bean詳解
這篇文章主要給大家介紹了關(guān)于如何在Spring中使用編碼方式動(dòng)態(tài)配置Bean的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05