springboot單體項目的執行流程

首先就是啟動springboot項目,即執行主函數,這個主函數的類通常帶有SpingBootApplication注解,類中的main方法就是程序的入口。

啟動主函數后,SpringBoot會按特定順序加載配置文件,如application.properties或application.yml,這兩種格式的文件都行,還能根據不同的環境加載不同的加載文件,如生產環境,測試環境等。配置文件里一般包含數據庫連接的信息,服務端接口,日志級別等。

接著main函數中的run方法會創建一個Spring容器負責管理項目中的Bean,具體過程就是在調用SpingApplication.run方法時,會先創建一個SpringApplication實例,該實例會進行如下工作:

? ?1.推斷應用類型,判斷時Web應用還是非Web應用。

? ?2.查找并加載初始化器(ApplicationContextInitializer),這些初始化器可以在? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ApplicationContext(應用上下文,是一個管理Spring應用中各種組件如Bean,配置信息,時間等的高級容器)刷新之前進行自定義配置。

? 3.查找并加載監聽器,監聽器會監聽應用啟動過程中的各種時間,如應用啟動,上下文刷新等。

? 4.推斷主應用類,即包含main方法的類

然后SpringApplition實例會根據應用類型創建相應的ApplicationContext實例。

接下來就是加載Bean定義,ApplicationContext會加載所有的Bean定義,這些Bean定義可以來自多個地方:

? ?1.通過@ComponentScan掃描指定路徑下的帶有@Component,@Service,@Repository,? ? ? ? ? @Controller等注解的類

? ?2.@Configuration注解的配置類中使用@Bean注解定義的類

?接著就是在Applicationtext刷新的過程中,會根據Bean定義創建Bean實例,并進行依賴注入和生命周期管理。Spring容器會確保Bean的單例性(默認情況下,也可以指定為多例),并處理Bean的初始化和銷毀方法。

在Sping容器和Bean加載完成后,還會啟動服務器,執行命令運行器和應用啟動運行器(對實現了CommandLineRunner或ApplicationRunner接口的Bean在應用啟動后執行一些初始化操作),最后發布應用啟動完成事件。

講完了springboot的啟動后下面就是交互過程了。

客戶端發起請求,這個請求是HTTP請求,它包括如下方法:

? 1.請求方法:常見的有GET(用于獲取資源),POST(用于提交數據),PUT(用于更新資源),DELETE(用于更新資源),DELETE(用于刪除資源)等

? 2.請求URL:指明要訪問的資源地址

? 3.請求頭:攜帶關于請求的額外信息,包含很多信息,如客戶端類型,請求體的數據格式,請求發送的日期時間,身份驗證(例如把token放到請求頭中)等等

? 4.請求體:POST,PUT等方法可能會攜帶請求體,用于傳遞數據,數據格式可以是JSON,XML等

? 接著請求到達了SpringBoot應用所監聽的端口,在請求到達之前,服務器一直在監聽該端口,端口一般是8080。

嵌入式服務器接收到請求后,會進行如下操作:

? 1.將原始的HTTP請求封裝成HttpServletRequest對象,該對象提供了一系列方法用于獲取請求的各種信息,如請求方法,請求URL,請求頭,請求體等。

? 2.同時創建一個HttpServletResponse響應對象,用于后續后端向前端返回消息

請求在到達DispatcherServlet之前,會經過一系列過濾器,過濾器可以實現編碼轉換,請求日志,權限驗證等功能,通過實現Filter接口來定義過濾器。

DispatcherServlet作為SpringMVC的核心調度器,繼承自HttpServlet,在SpringBoot啟動時自動配置和初始化,接受經過過濾器鏈處理后的請求。

在查找處理器(三層架構中的controller)之前,DispatcherServlet會進行一些預處理操作:

? 1.檢查請求是否為文件上傳請求,若為文件上傳請求,則將請求包裝成MultipartHttpServletRequest。

? 2.根據請求的Accept頭確定合適的消息轉換器,用于后續處理響應數據的格式轉換

(這里的Accept頭是HTTP請求頭中的一個字段,他用于告知服務器客戶端能夠接受的響應內容類型)

HandlerMapping根據請求的URL和請求方法,從被@Controller或@RestController注解標記的類中查找對應的處理器方法。常見的HandlerMapping實現是RequestMappingHandlerMapping,它依據@RequestMapping,@GetMappingdeng等注解來匹配處理器方法。

在確定請求對應的處理器之后,調用處理器方法之前,會執行攔截器的preHandle方法。攔截器是SpringMVC提供的功能,可用于對處理器方法進行增強,如權限驗證,日志記錄,性能監控等。

示例:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 權限驗證if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/login");return false;}// 記錄請求開始時間request.setAttribute("startTime", System.currentTimeMillis());return true;}
}

若攔截器的preHandle方法返回true,HandlerAdapter會將請求中的參數(如URL參數,請求體參數等)綁定到處理器方法的參數上,并調用處理器方法。在這個過程中,控制器可能會調用服務層的方法來處理業務邏輯。

服務層主要負責處理業務規則,數據訪問和事務管理等操作。控制器調用服務層的方法,服務層再調用數據訪問層(DAO)來與數據庫或其他數據源進行交互。

數據訪問層負責與底層數據源進行交互,執行數據的增刪改查,通常用mybatis或者mybatisplus進行實現。

處理器方法執行完成后,在視圖渲染之前,會執行攔截器的postHandle方法。此方法可用于對處理器方法的執行結果進行修改或補充。

處理器方法處理完業務邏輯后,返回一個結果。結果可以是視圖名稱(用于視圖渲染),也可以是數據對象(如JSON,XML等)。如果使用@RequestController注解,默認會將返回的對象轉換為JSON格式返回給客戶端。

若處理器方法返回的是視圖名稱,DispatcherServlet會使用ViewResolver解析視圖,將模型數據傳遞給視圖模版進行渲染。

視圖模板將模型數據和視圖模版合并,生成最終的HTML頁面。(如果有)

在整個請求處理完成后,包括視圖渲染完成,會執行攔截器的afterComletion方法。此方法主要用于進行資源清理操作,如關閉數據庫連接,記錄請求處理的總時長等。

處理器方法返回的結果(視圖或數據)被封裝到HttpServletResponse對象中,DispatcherServlet設置響應的狀態碼,響應頭和響應體。

響應在返回客戶端之前,再次經過過濾器,過濾器可對響應進行后置處理,如添加響應頭,壓縮響應數據等。

嵌入式服務器將HttpServletResponse對象中的響應數據返回給客戶端,客戶端根據響應內容進行相應處理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78531.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78531.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python格式化字符串的四種方法

Python格式化字符串的四種方法 1.使用 % 運算符 %s 是一個字符串的占位符,而 “World” 是替換它的值 print("Hello, %s!" % "World") # 輸出:Hello, World!你可以使用多個占位符 注意:多個變量占位,變量要…

【Redis】緩存|緩存的更新策略|內存淘汰策略|緩存預熱、緩存穿透、緩存雪崩和緩存擊穿

思維導圖: Redis最主要的用途,三個方面: 1.存儲數據(內存數據庫) 2.緩存(redis最常用的場景) 3.消息隊列 一、什么是緩存 我們知道對于硬件的訪問速度來說,通常情況下&#xff1…

中陽視角下的趨勢確認策略:以數據為核心的交易思維

中陽視角下的趨勢確認策略:以數據為核心的交易思維 在動態交易市場中,如何在波動中捕捉相對確定的趨勢,是每一位操作者關心的問題。“中陽”理念主張通過結構性價格分析,判斷市場情緒的拐點。尤其是在出現大陽線或中陽線時&#x…

【C/C++】inline關鍵詞

C inline 關鍵字學習筆記 一、什么是 inline 函數? inline(內聯)是 C 中的一個關鍵字,表示“將函數的代碼直接插入到調用點”,以減少函數調用開銷,提升執行效率。 ? 注意:inline 是一種“請求…

React useMemo函數

第一個參數是回調函數,返回計算的結果,第二個參數是依賴項,該函數只監聽count1變量的變化 import { useReducer, useState } from react; import ./App.css;// 定義一個Reducer函數 根據不同的action進行不同的狀態修改 function reducer(st…

對比測評:為什么AI編程工具需要 Rules 能力?

通義靈碼 Project Rules 在開始體驗通義靈碼 Project Rules 之前,我們先來簡單了解一下什么是通義靈碼 Project Rules? 大家都知道,在使用 AI 代碼助手的時候,有時候生成的代碼不是自己想要的,或者說生成的代碼采納后…

Java學習手冊:MyBatis 框架作用詳解

一、MyBatis 簡介 MyBatis 是一款優秀的持久層框架,用于簡化 JDBC 開發。它通過將 Java 對象與數據庫表之間的映射關系進行配置,使得開發者可以使用簡單的 SQL 語句和 Java 代碼來完成復雜的數據操作。MyBatis 支持自定義 SQL 語句,提供了靈…

list的設計

#pragma once #include<assert.h> #include<iostream> using namespace std; namespace aqc {template<class T>struct list_node{list_node* _next;list_node* _prev;T _data;list_node(const T& xT())//加const防止權限放大&#xff0c;用引用減少拷貝…

基于 PyQt 的YOLO目標檢測可視化界面+ nuitka 打包

在人工智能和計算機視覺領域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;是一種廣泛使用的實時目標檢測算法。為了直觀地展示YOLO算法的檢測效果&#xff0c;我們使用Pyqt框架進行檢測結果的可視化&#xff0c;同時為了使其能夠脫離Python環境&#xff0c;我們…

2.1 閱讀錯題---02-04年

引言 2002年-2004年英語閱讀錯題匯總與分析總結。 一、02年閱讀 Text 1 題目&#xff1a;21題 題型&#xff1a;細節題 原因&#xff1a;單詞認錯了&#xff0c;原句中 in sympathy with 譯為 與…一致 &#xff1b;題干中的 sympathy 譯為 同情 題目&#xff1a;22題 題…

Axure疑難雜癥:中繼器制作下拉菜單(多級中繼器高級交互)

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 本文視頻課程記錄于上述地址第五章中繼器專題第11節 課程主題:中繼器制作下拉菜單 主要內容:創建條件選區、多級中繼器…

即刻啟程,踏上W55MH32高性能以太網單片機學習之路!

單芯片解決方案&#xff0c;開啟全新體驗——W55MH32 高性能以太網單片機 W55MH32是WIZnet重磅推出的高性能以太網單片機&#xff0c;它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身&#xff0c;具體來說&#xff0c;一顆W55MH32內置高性能Arm Cortex-M3核心…

C++負載均衡遠程調用學習之上報功能與存儲線程池

目錄 1. Lars-reportV0.1 report模塊介紹 2.Lars-reporterV0.1 reporter項目目錄構建 3.Lars-ReporterV0.1 數據表和proto協議環境搭建 4.Lars-ReporterV0.1上報請求業務處理 5.Lars-ReporterV0.1上報請求模塊的測試 6.Lars-ReporterV0.2開辟存儲線程池-網絡存儲分離 1. L…

LabVIEW三軸電機控制

在工業自動化迅猛發展的當下&#xff0c;多軸伺服電機控制系統在制造業、3D 打印等眾多領域的需求與日俱增。它不僅要實現高精度的單軸運動控制&#xff0c;還需保障多軸協同作業的精準度&#xff0c;對響應速度也有嚴格要求。LabVIEW 開發多軸伺服電機控制系統&#xff0c;有效…

驅動開發硬核特訓 · Day 27(下篇):深入掌握 Common Clock Framework 架構與實戰開發

節。 在本篇內容中&#xff0c;我們將圍繞 Linux 內核中的時鐘子系統核心架構 —— Common Clock Framework&#xff08;簡稱 CCF&#xff09;展開深入講解&#xff0c;目標是幫助你全面理解其設計理念、主要數據結構、注冊流程、驅動實現方式&#xff0c;以及如何基于 NXP i.M…

數據庫基礎:數據庫類型與MySQL特點詳解

一、數據庫的主要類型 1. 關系型數據庫(RDBMS) 特點:基于關系模型,數據以表格形式存儲 代表產品:MySQL、Oracle、SQL Server、PostgreSQL 優勢:ACID事務支持、強一致性、成熟的SQL標準 適用場景:需要復雜查詢和事務支持的場景 2. 非關系型數據庫(NoSQL) 文檔型數據庫:Mo…

49認知干貨:產品的生命周期及類型匯總

49章:產品的生命周期與類型劃分 宇宙是運動的而非靜止的,任何事物亦是如此。只要是存在的事物,便必然存在周期性變化,就像四季更替中的冬日枯樹、春日新芽、夏日繁茂與秋日凋零。 這也意味著:事物的發展,離不開周期的更迭與演化,死亡并非終點,而是一種新的循環轉變。 …

【2025最新】為什么用ElasticSearch?和傳統數據庫MySQL與什么區別?

Elasticsearch 深度解析&#xff1a;從原理到實踐 一、為什么選擇 Elasticsearch&#xff1f; 數據模型 Elasticsearch 是基于文檔的搜索引擎&#xff0c;它使用 JSON 文檔來存儲數據。在 Elasticsearch 中&#xff0c;相關的數據通常存儲在同一個文檔中&#xff0c;而不是分散…

Docker安裝Gitblit(圖文教程)

本章教程,使用Docker安裝部署Gitblit。 一、Gitblit簡介 Gitblit 是一個基于 Java 的 Git 倉庫管理工具,主要用于在局域網或小型團隊環境中搭建私有 Git 服務器。它提供了一個簡單易用的 Web 界面,用于瀏覽代碼、管理倉庫和用戶權限等。 二、拉取鏡像 sudo docker pull git…

nDCG(歸一化折損累計增益) 是衡量排序質量的指標,常用于搜索引擎或推薦系統

nDCG&#xff08;歸一化折損累計增益&#xff09; 是衡量排序質量的指標&#xff0c;常用于搜索引擎或推薦系統。核心思想是&#xff1a;排名越靠前的高質量結果&#xff0c;對整體評分的貢獻越大&#xff0c;但后續結果的貢獻會逐漸“打折”。最終通過對比實際排序與理想排序的…