當前位置:首頁 » 操作系統 » mvc源碼分析

mvc源碼分析

發布時間: 2023-05-25 04:59:43

A. 有一點java基礎,如何成為一名java架構師

在Java程序員行業中,有不少Java開發人員的理想是成為一名優秀的Java架構師,Java架構師的主要任務不是從事具體的軟體程序的編寫,而是從事更高層次的開發構架工作。他必須對開發技術非常了解,並且需要有良好的組織管理能力。可以這樣說,一物雹個Java架構師工作的好壞決定了整個軟體開發項目的成敗。那麼Java架構師需要掌握哪些知識點呢?

1、框架源碼分析

設計模式:Singleton單例模式,Factory工廠模式,Proxy代理模式,Template模板模式,Prototype原型模式等

Spring5:Spring提醒結構,IOC注入原理,AOP設計原理,Spring事務處理機制,SpringMVC,Spring源碼分析。

Mybatis:Mybatis體系結構,Mybatis核心應用與配置,Mybatis關聯查詢,與Spring集成,Mybatis源碼分析。

2、性能優化

JVM性能優化:剖析JVM整體結構,詳解垃圾回收機制GC,JVM性能調優與工具排查

Nginx調優:Nginx項目架構,Nginx核心配置,Nginx負載演算法配置

Tomcat調優:Tomcat運行機制及框架,Tomcat線程模型,Tomcat性能調優

Mysql性能優化:SQL執行計劃,AQL優化,索引優化。

3、掌握池技術

對象池,連接池,線程池,Java反射技術,寫框架必備的技術,但是有嚴重的性能問題,替代方案Java位元組碼技術。

4、掌握nio,值得注意的是「直接內存」的特點,使用場景。

5、掌握Java多線程同步非同步。

6、掌握Java各種集合對象的實現原理,了解這些可以讓你在解決問題時選擇罩兄帆合適的數據結構,高效的解決問題。

7、熟練使用各種數據結構和演算法,數組、哈希、鏈表、排序樹就是一句話要麼是時間換空間要麼是空間換時間。

8、熟悉tcp協議,創建連接三次握手和斷開連接四次握手的塵旁整個過程,不了解的話,無法對高並發網路應用做優化。

9、熟悉http協議,尤其是http頭,我發現好多工作五年以上的都弄不清session和cookie的生命周期以及它們之間的關聯。

10、熟悉系統集群、負載均衡、反向代理、動靜分離,網站靜態化。

11、掌握分布式。

Java並發編程和網路編程:Java線程狀態,線程池,線程通信,線程安全,Netty高性能原理

分布式開發框架:分布式系統口調用技術:RPC,Apache分布式系統Zookeeper原理與應用,阿里Dubbo設計思想與應用

分布式中間件:分布式伺服器治理,分布式消息通信,分布式數據緩存,MongoDB企業集群解決方案

12、掌握資料庫的設計能力,對它基本的參數優化,慢查詢日誌分析,主從復制的配置,至少要成為半個mysqldba。

B. Spring全家桶筆記:Spring+Spring Boot+Spring Cloud+Spring MVC

最近我整理了一下一線架構師的Spring全家桶筆記:Spring+Spring Boot+Spring Cloud+Spring MVC,分享給大家一起學習一下~ 文末免費獲取哦

Spring是一個輕量級控制反轉(IoC)和面向切面(AOP)的容器框架。Spring框架是由於軟體開發的復雜性而創建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限於伺服器端的開發。從簡單性、可測試性和松耦合性角度而言,絕大部分Java應用都可以從Spring中受益。

1.1 Spring面試必備題+解析

1.2 Spring學習筆記

(1)Spring源碼深入解析

(2)Spring實戰

1.3 Spring學習思維腦圖

Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot致力於在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。

2.1 Spring Boot面試必備題+解析

2.2 Spring Boot學習筆記

(1)Spring Boot實踐

(2)SpringBoot揭秘 快速構建微服務體系

2.3 SpringBoot學習思維腦圖

springcloud是微服務架構的集大成者,將一系列優秀的組件進行了整合。基於springboot構建,對我們熟悉spring的程序員來說,上手比較容易。通過一些簡單的註解,我們就可以快速的在應用中配置一下常用模塊並構建龐大的分布式系統。

3.1 Spring Cloud面試必備題+解析

3.2 Spring Cloud學習筆記

(1)Spring Cloud參考指南

SpringMVC是一種基於Java的實現MVC設計模式的請求驅動類型的輕量級Web框架,使用了MVC架構模式的思想,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助我們簡化開發

4.1 Spring MVC面試必備題+解析

4.2 Spring MVC學習筆記

(1)看透Spring MVC源代碼分析與實踐

(2)精通Spring MVC

最後分享一下一份JAVA核心知識點整理(PDF)

C. spring mvc 常用註解詳解

前言

現在主流的Web MVC框架除了Struts這個主力 外,其次就是Spring MVC了,因此這也是作為一名程序員需要掌握的主流框架,框架選擇多了,應對多變的需求和業務時,可實行的方案自然就多了。不過要想靈活運用Spring MVC來應對大多數的Web開發,就必須要掌握它的配置及原理。

Spring mvc 介紹

Spring Web MVC是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架,即使用了MVC架構模式的思想,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助我們簡化開發,Spring Web MVC也是要簡化我們日常Web開發

image.png

spring mvc 常用註解詳解

@Controller

在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在SpringMVC 中提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實現特定的介面,只需使用@Controller 標記一個類是Controller ,然後使用@RequestMapping 等一些註解用以定義請求URL 請求和Controller 方法之間的映射,這樣的Controller 就能被外界訪問到。其標記在一個類上,使用它標記的類就是一個SpringMVC Controller 對象。分發處理器將會掃描使用了該註解的類的方法,並檢測該方法是否使用@RequestMapping 註解。@Controller 只是定義了一個控制器類,而使用@RequestMapping 註解的方法才是真正處理請求的處理器。此外我們還需要將controller注冊到spring里

@RequestMapping

RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑,作用於方法上,表明該處理器的請求地址=父路徑+方法上url+method,其擁有6個屬性

1、 value, method;定義處理器訪問的具體體質

value: 指定請求的實際地址,指定的地址可以是URI Template 模式;

method: 指定請求的method類型, GET、POST、PUT、DELETE等;

2、consumes,proces 定義處理器內容類型

consumes: 指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;

proces: 指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;

3、params,headers 定義處理器處理類型

params: 指定request中必須包含某些參數值,才讓該方法處理!

headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請求。

@PathVariable

用於將請求URL中的模板變數映射到功能處理方法的參數上,即取出uri模板中的變數作為參數。如:

@requestParam

@requestParam主要用於在SpringMVC後台控制層獲取參數,類似一種是request.getParameter("name"),它有三個常用參數:defaultValue = "0", required = false, value = "isApp";defaultValue 表示設置默認值,required 銅過boolean設置是否是必須要傳入的參數,value 值表示接受的傳入的參數類型。

@ResponseBody

作用: 該註解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式後,寫入到Response對象的body數據區。使用時機:返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json等)使用;

@RequestBody

該註解常用來處理Content-Type: 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等;它是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body,然後綁定到相應的bean上的。

spring mvc 攔截器配置

preHandle:預處理回調方法,返回值:true表示繼續流程,false表示流程中斷(如登錄檢查失敗),不會繼續續調用其他的攔截器或處理器,此時我們需要通過response來產生響應;

postHandle:後處理回調方法,實現處理器的後處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數據進行處理或對視圖進行處理,modelAndView也可能為null。

afterCompletion:整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源清理,類似於try-catch-finally中的finally,但僅調用處理器執行鏈中preHandle返回true的攔截器的afterCompletion。

spring mvc 靜態資源放問配置

image.png

spring mvc 文件上傳

前端

後端

spring mvc 工作流程詳解

image.png

1、 用戶發送請求至前端控制器DispatcherServlet。

2、 DispatcherServlet收到請求調用HandlerMapping處理器映射器。

3、 處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截器(如果有則生成)一並返回給DispatcherServlet。

4、 DispatcherServlet調用HandlerAdapter處理器適配器。

5、 HandlerAdapter經過適配調用具體的處理器(Controller,也叫後端控制器)。

6、 Controller執行完成返回ModelAndView。

7、 HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。

8、 DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。

9、 ViewReslover解析後返回具體View。

10、DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。

11、 DispatcherServlet響應用戶。

如果你也對Java架構比如分布式、微服務、源碼分析、性能優化、高並發高可用等技術感興趣可以在手機上面私信我,回復「架構」二字即可免費領取一套價值3880的架構資料哦。

D. 淺談SpringMvc HttpMessageConverter

1.HttpMessageConverter是SpringMvc框架中一個重要的組件,其主要職責是對@RequestBody的解析(該註解作用就是告訴mvc,這個參數由Http的請求頭,經過HttpMessageConverter解析得到)

看一下該介面

該介面的canRead方法表指虧示其支持的Class類型,MediaType是其支持的http的ContentType類型,假如一個Http請求是Application/json,Mvc框架會去尋找支持該MediaType的Converter,然後再判斷@RequestBody註解對應的class類型是否支持,如果支持,那麼就交由對應的MessageConverter去解析。

另一個問題就是,這個類是解析什麼呢,實際上,HttpInputMessage是指HttpServletRequest的Body的流汪槐,可以看介面。

那麼Mvc框架的部分核心我們就能猜到了,一個Http請求過來,包括Header和Body,對於其中的困逗友Body的流將會被DispatcherServlet包裝成SpringMvc的HttpRequest,然後委託RequestChainExecutor,經過一系列處理,最終Body的流到了HttpMessageConverter(這里不是那麼准確),重點需要理解的就是一個Http請求,頭部會被HttpMessageConverter獲取並解析,如果找不到對應的HttpMessageConverter,Spring框架會報異常。

一般情況下,我們常見的有StringHttpMessageConverter(text/plain+String),ByteArrayHttpMessageConverter(application/octet-stream+byte[]),FormHttpMessageConverter(好幾個),FastJsonHttpMessageConverter(application/json+Object)等。

如果要自定義一個HttpMessageConverter,只要繼承AbstractHttpMessageConverter就可以,其中運用了模板方法,具體的邏輯組織在AbstractHttpMessageConverter中已經實現,只需要實現以下方法和構造方法就可以使用了。

該部分就是,將HttpMessage(通過容器的HttpRequest獲得相關屬性),首先read請求時,直接轉readInternal(子類實現),如果是write響應,則先判斷返回的結果類型是不是流,是流就直接構建Message響應(返迴流,如果直接讀取就會被消費了,流只能讀一次,對應的就是Controller(MethodHandler)的返回結果),如果是其他類型,則交由實現類將JavaObject變成流。

綜上所述,HttpMessageConverter就是負責將Http請求的Body與JavaObject之間進行轉換,那麼在哪裡可以配置呢?在WebMvcConfigurationSupport的configureMessageConverters中可以配置,默認情況boot會在存在對應classPath時自動注入mvc相關配置,而關於HttpMessageConverter在不重寫configureMessageConverters時默認配置一堆,一旦自定義配置了,就只支持自己定義的幾個了。

關於模板方法,在中也有使用到,同樣的套路,父類定義方法模板(骨架),子類實現邏輯原語。

對於一個Http請求,Tomcat(一定猜測)首先監聽埠,收到請求就委託一個Thread去初始化Servlet或者執行Servlet,並通過ThreadLocal來保存HttpServletContext和HttpRequest與HttpResponse,如果去測試的話,你會發現Tomcat基於裝飾器模式用RequestFacade,ResponseFacade封裝了Request和Response,請求到DispatcherServlet,SpringMvc則解析請求頭(可以重復解析)和請求Body,通過請求頭方法類型交給doDispatch進行解析,最終交給RequestChainExecutor去執行,通過請求頭得到路徑交給不同的MethodHandler(Controller介面與@Controller)去處理。根據MethodHandler對應方法的註解(@RequestBody,@ResponseBody,@PathVariable等)來交給HttpMessageConverter(Body的解析)、Converter(默認的非Body的解析)、HandlerMethodArgumentResolver(報文頭解析及前置處理)、(方法返回參數處理)等進行Http報文和JavaObject的轉換。

我實在懶得寫清除細節了,截圖頭疼,沒必要深究源碼(太細節了),先搞清楚Mvc的各個組件再說。

Mvc 數據流

Http(Header+Body)->HttpMessage(Body)->HttpMessageConverter->JavaObject

                                                       (Header)->Converter+Format SPI

Mvc Controller拓展

MethodHandler+MethodHandlerInterceptor+HandlerMethodArgumentResolver+

+Aspect(有些拓展基於代理)

E. vertx獲取所有的handler

Vert.x - 學習記錄 - 只有一二三的博客 - CSDN博客
2020年12月22日真正調用處理邏輯的入口往往是處理器(Handler),Vert.x保證同一個普通Verticle(也就是EventLoop Vert...



CSDN編程社區

Vert.x - SpringBoot 整合 vertx - 小畢超的博客 - CSDN博客 - vertx

1. vertx 前面的文章講解了 vertx 的簡介及 vertx-web 的路由,看過的小夥伴應該對 vertx 有了一定的了解,從前面的演示來看,都
2. SpringBoot 整合 vertx 首先新建一個 SpringBoot 項目,注意不要引入其他 web 框架。在 pom 中引入依賴,注意這里我使用的是 vertx 4.1.
CSDN編程社區

二. Vert.x - Web開發之路由 - 知乎

第一種就是get請求直接拼接在URL後的參數,比如:http://localhost:8080/method?param=hello router.route(HttpMethod.GET, "/method").handler(request
第二種是獲取路徑的參數,比鉛核如:http://localhost:8080/method/xiaoming/xm123 // 獲取參數 router.route(HttpMethod.GET, "/method/:user/:
第三種是獲取到請求體中的數據,也就是post提交的數據。這個稍微有一些繁瑣,首先要指定一個BodyHandler,然後才能通過requestContext對象來獲取body體中的數據。獲取body
知乎

Vert.x學習筆記(一) Vert.x 核心包 - 蒲公英雲
6月11日創建Vertx對象 要使用Vertx的第一步就是創建Vertx對象,所有API都要通過這個對象來調用。一般情況下,一個程序只需要一個Vertx對象即可,不過有...
蒲公英雲

vert.x學習(七),使用表單獲取用戶提交的數據 | 表單
router.post("/user")的作用是當用戶在表單頁面點擊保存按鈕後,觸發post請求,vert.x會將這個請求路由到router.post("/user").handler裡面,在...
www.lmlphp.com

深入槐仔掘淺出Vert.x 第一季 第6集 Vert.x獲取請求參數戚旅——body參數

231次播放

07:25
合集
深入淺出Vert.x 第一季 vertx快速入門 java高性能非同步非阻塞框架

聽歌不循環
2020年10月21日

Vertx-web第三課 bodyhandler


38:49
合集
Vertx4.*

嗶哩嗶哩
2021年07月10日

...框架的使用體驗(一) - 程小明的coding的博客 - CSDN博客 - vertx 並發
6月21日Vert.x的Handler內部是atomic/原子操作,Verticle內部是thread safe/線程安全的,Verticle之間傳遞的數據是immutable/不可改變的。
CSDN編程社區

源碼分析 - Vertx入門和源碼淺析 - 個人文章 - SegmentFault 思否
1. Vertx 實現類VertxImpl,它的重要線程 eventLoopGroup acceptorEventLoopGroup
2. Verticle 1) Verticle起作用的方式,主要是通過Vertx進行部署,也就是deployVerticle 2) Verticle部署,主要是Vertx框架把vertx 和context 傳給Verticle
3. Context上下文 1) 子類:ContextInternal EventLoopContext 2) 上下文是通過Vertx創建,如ContextInternal callingContext = vertx.getOrCreateContext(); 3
思否開發者社區

vertx web記錄route 每個handler的執行時長 - 蒲公英雲
1. 配置route,將route模塊載入到vertx中,vertx通過調用listen方法綁定監聽
2. 請求到來之後,調用 listenContext.runOnContext將請求交給route模塊處理
3. 模塊handler會創建VertxThread,並開啟一個由vertx管理的線程進行處理
蒲公英雲

06-架構師-SpringMVC如何獲取handler源碼分析




22:16
合集
架構師專場——springmvc

F. springbootmavenplugin必須要有嗎

-Version: 1.0
Created-By: Maven Archiver 3.4.0
Build-Jdk-Spec: 11
Implementation-Title: springbootfirst
Implementation-Version: 0.0.1-SNAPSHOT
SpringBoot插件生成的jar包行困結構為

BOOT-INF/classes 中包含項目所有的class文件,BOOT-INF/lib 下包含項目依賴的第三方jar包,MANIFEST.MF文件內容為

Manifest-Version: 1.0
Created-By: Maven Archiver 3.4.0
Build-Jdk-Spec: 11
Implementation-Title: springbootfirst
Implementation-Version: 0.0.1-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.imooc.springbootfirst.SpringbootfirstApplication
Spring-Boot-Version: 2.1.6.RELEASE
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
插件是如何找到啟動類的
描述文件中納芹的Start-Class就是我們項目的啟動類,我們可以查看插件源碼來分析

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
先引入插件的maven依賴

RepackageMojo就是repackage打包要執行的邏輯,核洞帶畢心類為Repackager

在插件創建MANIFEST.MF文件過程中,如果我們沒有配置MainClass屬性,就會通過MainClassFinder類來查找MainClass

private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";

protected String findMainMethod(JarFile source) throws IOException {
return MainClassFinder.findSingleMainClass(source, this.layout.getClassesLocation(),
SPRING_BOOT_APPLICATION_CLASS_NAME);
}
在所有類中查找包含SpringBootApplication註解且包含main方法的類,並當做啟動類,內部通過ASM位元組碼庫來解析class文件得到類信息。

啟動流程
java -jar springbootfirst-0.0.1-SNAPSHOT.jar
java啟動jar包會找META-INF/MANIFEST.MF文件中的Main-Class來啟動,SpringBoot插件最終生成的Main-Class為 org.springframework.boot.loader.JarLauncher類。

/**
* jar包類型的啟動器
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.0.0
*/
public class JarLauncher extends ExecutableArchiveLauncher {

static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";

static final String BOOT_INF_LIB = "BOOT-INF/lib/";

public JarLauncher() {
}

protected JarLauncher(Archive archive) {
super(archive);
}

@Override
protected boolean isNestedArchive(Archive.Entry entry) {
if (entry.isDirectory()) {
return entry.getName().equals(BOOT_INF_CLASSES);
}
return entry.getName().startsWith(BOOT_INF_LIB);
}

public static void main(String[] args) throws Exception {
new JarLauncher().launch(args);
}

}
最終運行的是MANIFEST.MF文件中Start-Class,值為com.imooc.springbootfirst.SpringbootfirstApplication,其實就是我們項目中配置的啟動類。

/**
* 啟動器
*
* @author Phillip Webb
* @author Dave Syer
* @since 1.0.0
*/
public abstract class Launcher {

/**
* 啟動流程
*/
protected void launch(String[] args) throws Exception {
JarFile.registerUrlProtocolHandler();
//根據BOOT-INF/classes下的class文件和BOOT-INF/lib下的第三方jar包創建Archive
//創建的ClassLoader為LaunchedURLClassLoader類型
ClassLoader classLoader = createClassLoader(getClassPathArchives());
launch(args, getMainClass(), classLoader);
}

/**
* 創建新的LaunchedURLClassLoader,從多個URL中載入class
*/
protected ClassLoader createClassLoader(URL[] urls) throws Exception {
return new LaunchedURLClassLoader(urls, getClass().getClassLoader());
}

/**
* 將新的類載入器設置到線程上下文中,並啟動應用程序
*/
protected void launch(String[] args, String mainClass, ClassLoader classLoader) throws Exception {
Thread.currentThread().setContextClassLoader(classLoader);
createMainMethodRunner(mainClass, args, classLoader).run();
}

/**
* 創建一個Main方法運行器來啟動應用程序
*/
protected MainMethodRunner createMainMethodRunner(String mainClass, String[] args, ClassLoader classLoader) {
return new MainMethodRunner(mainClass, args);
}

}
創建新的ClassLoader類型LaunchedURLClassLoader,從BOOT-INF/classes下和BOOT-INF/lib下的所有jar包中載入class。載入我們整個項目的都是LaunchedURLClassLoader類載入器。

/**
* 一個執行Main方法的工具類
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.0.0
*/
public class MainMethodRunner {

private final String mainClassName;

private final String[] args;

/**
* Create a new {@link MainMethodRunner} instance.
* @param mainClass the main class
* @param args incoming arguments
*/
public MainMethodRunner(String mainClass, String[] args) {
this.mainClassName = mainClass;
this.args = (args != null) ? args.clone() : null;
}

public void run() throws Exception {
//使用線程上下文類載入器載入MainClass,就是我們項目中的SpringbootfirstApplication
Class<?> mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName);
//執行Main方法
Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
mainMethod.invoke(null, new Object[] { this.args });
}
}
參考
springboot 打包插件spring-boot-maven-plugin打包機制及內部結構分析

分類: spring
標簽: spring, maven, java
好文要頂 關注我 收藏該文
strongmore
粉絲 - 9 關注 - 5
+加關注
00
« 上一篇: IDEA中對非Maven項目導出jar包
» 下一篇: java實現對圖片打馬賽克
posted @ 2021-11-04 18:50  strongmore  閱讀(6395)  評論(0)  編輯  收藏  舉報
刷新評論刷新頁面返回頂部
登錄後才能查看或發表評論,立即 登錄 或者 逛逛 博客園首頁
【推薦】阿里雲新人特惠,爆款雲伺服器2核4G低至0.46元/天
編輯推薦:
· 一次 SQL 調優,聊一聊 SQLSERVER 數據頁
· 終於弄明白了 RocketMQ 的存儲模型
· 應屆畢業生程序員在面試時如何做好自我介紹?
· Redis 網路模型究竟有多強
· 不規則圖形背景排版高階技巧 -- 酷炫的六邊形網格背景圖
閱讀排行:
· 來自一位十年.net研發老人的吐血整理:.Net技術棧-網址導航
· 做演算法的這一年——2022年個人年終總結
· .Net 7 團隊把國內的龍芯確實當做一等公民和棄用的項目
· 我希望來年,更多是靠關系和模式掙錢——2022年我的總結與思考
· 平淡詳和的一年——2022年個人總結與思考
昵稱: strongmore
園齡: 3年7個月
粉絲: 9
關註: 5
+加關注
< 2023年1月 >
日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4
5 6 7 8 9 10 11
搜索
 找找看
 谷歌搜索
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
我的標簽
最新隨筆
1.單元測試框架之Junit使用及原理分析
2.Kotlin學習之反射
3.Kotlin學習之Kotlin和Java之間相互調用
4.Kotlin學習之函數
5.Kotlin學習之委託
6.Kotlin學習之面向對象
7.Kotlin學習之基本語法
8.SpringMVC整合Swagger簡單使用及原理分析
9.SpringMVC源碼分析之一個請求的處理
10.Spring整合Mqtt原理分析
我的標簽
java(220)
演算法(40)
數據結構(39)
spring(30)
設計模式(28)
python(11)
多線程(8)
踩坑(8)
linux(8)
kotlin(8)
更多
積分與排名
積分 - 174759
排名 - 6340
隨筆分類
c語言(2)
html(2)
java(136)
js(4)
kotlin(7)
leetcode(11)
linux(8)
python學習之旅(8)
spring(28)
機器學習(1)
數據結構與演算法(34)
網路(2)
隨筆檔案
2022年6月(6)
2022年5月(28)
2022年4月(12)
2022年3月(5)
2022年2月(1)
2021年11月(3)
2021年10月(6)
2021年9月(13)
2021年8月(21)
2021年7月(13)
2021年6月(9)
2021年5月(6)
2021年4月(11)
2021年3月(21)
2021年2月(5)
更多
閱讀排行榜
1. java中文轉拼音(12794)
2. java操作yaml文件(9029)
3. java實現圖片壓縮(7791)
4. jdk8升級jdk11踩坑記錄(lombok版本不兼容)(7465)
5. IDEA版本和Maven版本不兼容的問題(6840)
評論排行榜
1. Lombok原理分析及簡單實現(4)
2. java中BloomFilter(布隆過濾器)簡單使用(3)
3. java中如何通過程序檢測線程死鎖(1)
4. Spring中表達式語言spring-expression簡單使用(1)
5. 關於100個人隨機給錢的模擬實驗(1)
推薦排行榜
1. MurmurHash演算法簡單介紹(2)
2. java操作yaml文件(2)
3. java進行PDF和圖片之間的相互轉換(2)
4. JMX簡單入門(2)
5. 瀏覽器的DNS解析過程分析(1)
最新評論
1. Re:Spring中表達式語言spring-expression簡單使用
支持

--我叫城北徐公
2. Re:java中BloomFilter(布隆過濾器)簡單使用
@strongmore 好的好的,感謝回復~~...
--言小蹊
3. Re:java中BloomFilter(布隆過濾器)簡單使用
@言小蹊 在IDEA上...
--strongmore
4. Re:java中BloomFilter(布隆過濾器)簡單使用
您好,請問您這是是如何查看內存使用情況的?您是在eclipse上運行的代碼嗎?

--言小蹊
5. Re:java實現一個短URL生成器
博主介紹的短鏈接生成核心代碼的確挺實用的,短鏈接就是將長的網頁址通過技術方法進行縮短為短串。其實短鏈接只有生成和跳轉還不能滿足實際業務需求,還需要考慮其使用場景,目前短鏈接使用場景主要是簡訊內帶短鏈接...
--縮鏈
Copyright © 2023 strongmore
Powered by .NET 7.0 on Kubernetes
1. 前言
2. 打包原理
3. 插件是如何找到啟動類的
4. 啟動流程
5. 參考

G. SpringMVC

一、SpringMVC應用
1.springmvc是一個表現層的框架
經典三層架構:表現層, service層, 層。
Spring MVC和Struts2一樣,都是 為了解決表現層問題 的web框架,它們都是基於 MVC 設計模
式的。而這些表現層框架的主要職責就是處理前端HTTP請求。
Spring MVC 本質可以認為是對servlet的封裝,簡化了我們serlvet的開發
2.工作流程:
開發過程:
請求處理流程:
九大組件:
3.請求參數綁定,說白了SpringMVC是如何接受參數的:
原生servlet接收一個整型參數:
SpringMVC框架對Servlet的封裝,簡化了servlet的很多操作,SpringMVC框架對Servlet的封裝,簡化了servlet的很多操作
參數綁定:取出參數值綁定到handler⽅法的形參上
默認支持 Servlet API 作為方法參數:
綁定簡單類型參數:
綁定Pojo類型參數:
綁定Pojo包裝對象參數:
綁定日期類型參數(需要配置自定義類型轉換器):
4.Restful風格
什麼是Restful:
什麼是rest:
Restful的優點:
Restful的特性:
Restful的示例:
SpringMVC如何支持Restful風格的請求:
5.Ajax Json交互
交互:兩個方向
什麼是Json:
@ResponseBody註解:
分析SpringMVC使用Json交互:
二、SpringMVC高級技術
1.攔截器(Inteceptor)使用
監聽器、過濾器、攔截器的對比:
攔截器的執行流程:
多個攔截器的執行流程:
自定義SpringMVC攔截器:
2.處理multipart形式的數據
文件上傳:
3.在控制器中處理異常:
4.基於Flash屬性的跨重定向請求數據傳遞:
三、手寫SpringMVC框架:
四、SpringMVC源碼剖析
1.前端控制器 DispatcherServlet 繼承結構:
2.重要時機點分析
SpringMVC處理請求的流程即為:
3.核心步驟getHandler方法剖析:
4.核心步驟getHandlerAdapter方法剖析:
5.核心步驟ha.handle方法剖析:
6.核心步驟processDispatchResult方法剖析:
7.SpringMVC九大組件初始化:
五、SSM整合
1.整合策略:先整合Spring + Mybatis,然後再整合SpringMVC
2.Mybatis整合Spring
3.整合SpringMVC

未完待補充完整。。。

H. 從源碼理解總結web容器、spring容器、spring mvc容器三者關系

本篇,我打算從springMVC項目的web.xml的配置文件入手,通過部分源碼逐步去理解解釋三個容器的關系以及調用順序,因為是基於我個人的理解,可能有所不足。

一般web.xml文件里會有如下兩段配置信息:

我們先了解下web.xml,以下引用自 《web.xml文件是什麼?有什麼用?--詳解》 :

然後結合我們上面的web.xml中關於spring和spring mvc的配置信息來進入話題:

    首先,啟動web容器的時,會先生成對應項目的ServelContent對象,這個是每個項目的上下文,這個ServelContent可以管理所有的servlet,並將我們web.xml中設置的<context-param>內容作為鍵值對交給這個對象。

    然後載入<listener>標簽內容,這個時候就會產生org.springframework.web.context.ContextLoaderListener。

spring的這個 ContextLoaderListener 在接下來的過程中很重要,我們來看一下源碼

首先,可以看出它繼承了ContextLoader類,並實現了ServletContextListener介面。

這里再直接引用他人的結論   《Spring中ContextLoaderListener作用》

好了,人家說法中回到我們的起點了,我們基本都被人告知「ContextLoaderListener的作用是創建並初始化spring容器」

那我們就可以深入進去看看,到底哪裡做了這一步:

首先,我們知道了ServletContextListene是ServletContext的監聽者,監聽器的響應動作就是在伺服器啟動時contextInitialized會被調用,關閉的時候contextDestroyed被調用,這個好理解,那我們就來看一下ContextLoaderListener重寫的contextInitialized方法到底做了什麼。

我們再進入觀察initWebApplicationContext方法細看

我因為自己消化過一遍,直接給出關鍵位置的方法說明——

1、首先是278行:創建了WebApplicationContext,我們可以理解為spring容器的殼子有了

2、其次是288和289行:對ApplicationContext載入了配置文件,並設置servletContext為WebApplicationContext的parent,到這一步,可以理解為我們的spring容器也就差不多成型了

3、接下來是294行:把ApplicationContext對象以鍵值對的形式存到servletContext中,這一步很關鍵,就是因為servletContext中存在這個鍵值對,所以其他內部成員可以通過servletContext訪問到ApplicationContext,當然也能使用其管理的bean,而spring mvc則沒有這樣存在servletContext,所以我覺得正是這一步決定了子容器springmvc可以取用父容器內的bean,反著則不然。

接下來直到輪到我們的springmvc容器<servlet>標簽內容

會生成控制org.springframework.web.servlet.DispatcherServlet,這是一個前端控制器,主要的內容我之前也有一篇文章做過自我記錄

《Spring MVC的工作機制簡單理解》

我們可以看到設置的

<load-on-startup>1</load-on-startup>

這個標簽大概意思就是:

1、load-on-startup 元素標記容器是否應該在web應用程序啟動的時候就載入這個servlet,(實例化並調用其init()方法)。

2、它的值必須是一個整數,表示servlet被載入的先後順序。

3、如果該元素的值為負數或者沒有設置,則容器會當Servlet被請求時再載入。

4、如果值為正整數或者0時,表示容器在應用啟動時就載入並初始化這個servlet,值越小,servlet的優先順序越高,就越先被載入。值相同時,容器就會自己選擇順序來載入。

在DispatcherServlet的時候就根據springMVC容器容器的配置文件生成。

比如我這邊就是

那順序確定了,我們再看一下spring和spring mvc的父子關系哪裡確定:

我們可以從下面3個截圖看到dispatcherServlet的繼承關系,同時,init方法用的是dispatcherServlet父類的父類的方法。

重點在於initServletBean()方法,經過追蹤,我們找到該方法的最終實現又是在dispatcherServlet的父類FrameworkServlet中

其中涉及父子關系的實際是在219行的initWebApplicationContext()方法

initWebApplicationContext()方法主要用於創建或刷新WebApplicationContext實例,並對Servlet功能所使用的變數進行初始化。

從238行源碼就可以看到,它獲得ContextLoaderListener中初始化的rootContext,

在246行設置了父子關系的引用,也就是從這一點我們看到了spring和springMVC的父子關系!

並且,可以看到這只是一條單向的引用,spring中沒有引用直接指向springMVC,也就是子類能找到父類,然而父類都不知道這個子類,父子容器之間內部對象調用關系更明了。

再通過構造函數和Servlet的contextAttribute屬性查找ServletContext來進行webApplicationContext實例的初始化,最終。

這個方法內263行源碼onRefresh(wac)方法是FrameworkServlet提供的模板方法,在子類,也就是我們的DispatcherServlet的onRefresh()方法中進行了重寫。而在onRefresh()方法中調用了initStrategies()方法來完成初始化工作,初始化Spring MVC的9個組件。

1、Tomcat在啟動時給每個Web應用創建一個全局的上下文環境,這個上下文就是ServletContext,其為後面的Spring容器提供環境。

2、Tomcat在啟動過程中觸發容器初始化事件,Spring的ContextLoaderListener會監聽到這個事件,它的contextInitialized方法會被調用,在這個方法中,Spring會初始化全局的Spring根容器,這個就是Spring的IoC容器,IoC容器初始化完畢後,Spring將其存儲到ServletContext中,便於以後來獲取。

3、Tomcat在啟動過程中還會掃描Servlet,一個Web應用中的Servlet可以有多個,以SpringMVC中的DispatcherServlet為例,這個Servlet實際上是一個標準的前端控制器,用以轉發、匹配、處理每個Servlet請求。

4、Servlet會在容器啟動時載入或延遲載入(根據啟動級別設置數字)。延遲載入時,當第一個請求達到時,serlet容器發現對應Servlet還沒有被實例化,就調用Servlet的init方法。

在spring MVC里

        DispatcherServlet在初始化的時候會建立自己的容器,叫做SpringMVC 容器,用來持有Spring MVC相關的Bean。同時,Spring MVC還會通過ServletContext拿到Spring根容器,並將Spring根容器設為SpringMVC容器的父容器,請注意,Spring MVC容器可以訪問父容器中的Bean,但是父容器不能訪問子容器的Bean, 也就是說Spring根容器不能訪問SpringMVC容器里的Bean。

        說的通俗點就是,在Controller里可以訪問Service對象,但是在Service里不可以訪問Controller對象。

I. 詳解Spring mvc工作原理及源碼分析

Model 模型層 (javaBean組件 = 領域模型(javaBean) + 業務層 + 持久層)

View 視圖層( html、jsp…)

Controller 控制層(委託模型層進行數據處理)

springmvc是一個web層mvc框架,類似struts2。

springmvc是spring的部分,其實就是spring在原有基礎上,又提供了web應用的mvc模塊。

實現機制:

struts2是基於過濾器實現的。

springmvc是基於servlet實現的。

運行速度:

因為過濾器底層是servlet,所以springmvc的運行速度會稍微比structs2快。

struts2是多例的

springmvc單例的

參數封裝:

struts2參數封裝是基於屬性進行封裝。

springmvc是基於方法封裝。顆粒度更細。

⑴ 用戶發送請求至DispatcherServlet。

⑵ DispatcherServlet收到請求調用HandlerMapping查詢具體的Handler。

⑶ HandlerMapping找到具體的處理器(具體配置的是哪個處理器的實現類),生成處理器對象及處理器攔截器(HandlerExcutorChain包含了Handler以及攔截器集合)返回給DispatcherServlet。

⑷ DispatcherServlet接收到HandlerMapping返回的HandlerExcutorChain後,調用HandlerAdapter請求執行具體的Handler(Controller)。

⑸ HandlerAdapter經過適配調用具體的Handler(Controller即後端控制器)。

⑹ Controller執行完成返回ModelAndView(其中包含邏輯視圖和數據)給HandlerAdaptor。

⑺ HandlerAdaptor再將ModelAndView返回給DispatcherServlet。

⑻ DispatcherServlet請求視圖解析器ViewReslover解析ModelAndView。

⑼ ViewReslover解析後返回具體View(物理視圖)到DispatcherServlet。

⑽ DispatcherServlet請求渲染視圖(即將模型數據填充至視圖中) 根據View進行渲染視圖。

⑾ 將渲染後的視圖返回給DispatcherServlet。

⑿ DispatcherServlet將響應結果返回給用戶。

(1)前端控制器DispatcherServlet(配置即可)

功能:中央處理器,接收請求,自己不做任何處理,而是將請求發送給其他組件進行處理。DispatcherServlet 是整個流程的控制中心。

(2)處理器映射器HandlerMapping(配置即可)

功能:根據DispatcherServlet發送的url請求路徑查找Handler

常見的處理器映射器:BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping,

,(不建議使用)

(3)處理器適配器HandlerAdapter(配置即可)

功能:按照特定規則(HandlerAdapter要求的規則)去執行Handler。

通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展多個適配器對更多類型的處理器進行執行。

常見的處理器適配器:HttpRequestHandlerAdapter,,

(4)處理器Handler即Controller(程序猿編寫)

功能:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器才可以去正確執行Handler。

(5)視圖解析器ViewReslover(配置即可)

功能:進行視圖解析,根據邏輯視圖名解析成真正的視圖。

ViewResolver負責將處理結果生成View視圖,ViewResolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最後對View進行渲染將處理結果通過頁面展示給用戶。

springmvc框架提供了多種View視圖類型,如:jstlView、freemarkerView、pdfView...

(6)視圖View(程序猿編寫)

View是一個介面,實現類支持不同的View類型(jsp、freemarker、pdf...)

引入相關依賴:spring的基本包、springmvc需要的spring-webmvc,日誌相關的slf4j-log4j12,jsp相關的jstl、servlet-api、jsp-api。

因為DispatcherServlet本身就是一個Servlet,所以需要在web.xml配置。

一、使用默認載入springmvc配置文件的方式,必須按照以下規范:

①命名規則:-servlet.xml ====> springmvc-servlet.xml

②路徑規則:-servlet.xml必須放在WEB-INF下邊

二、如果要不按照默認載入位置,則需要在web.xml中通過標簽來指定springmvc配置文件的載入路徑,如上圖所示。

將自定義的 Controller 處理器配置到 spring 容器中交由 spring 容器來管理,因為這里的 springmvc.xml 配置文件中處理器映射器配置的是 BeanNameUrlHandlerMapping ,根據名字可知這個處理器映射器是根據 bean (自定義Controller) 的 name 屬性值url去尋找執行類 Handler(Controller) , 所以bean的name屬性值即是要和用戶發送的請求路徑匹配的 url 。

根據視圖解析路徑:WEB-INF/jsps/index.jsp

功能:根據bean(自定義Controller)的name屬性的url去尋找執行類Controller。

功能:自定義的處理器(Controller)實現了Controller介面時,適配器就會執行Controller的具體方法。

會自動判斷自定義的處理器(Controller)是否實現了Controller介面,如果是,它將會自動調用處理器的handleRequest方法。

Controller介面中有一個方法叫handleRequest,也就是處理器方法。

因此,自定義的Controller要想被調用就必須實現Controller介面,重寫Controller介面中的處理器方法。

熱點內容
好記星學習機家長管理密碼是多少 發布:2025-05-02 16:34:33 瀏覽:427
c編譯調試 發布:2025-05-02 16:32:57 瀏覽:142
sql查詢總成績 發布:2025-05-02 16:31:11 瀏覽:242
懷舊服德魯伊套裝如何配置 發布:2025-05-02 16:16:07 瀏覽:620
cydia安卓版怎麼用 發布:2025-05-02 16:10:29 瀏覽:630
二手輝昂哪個配置值得買 發布:2025-05-02 16:09:40 瀏覽:545
安卓耗子修改主要在哪個論壇 發布:2025-05-02 15:53:15 瀏覽:510
我的世界伺服器要求 發布:2025-05-02 15:43:52 瀏覽:903
改鍵精靈腳本怎麼用在Lol 發布:2025-05-02 15:37:14 瀏覽:613
電信頂盒密碼一般是多少 發布:2025-05-02 15:24:47 瀏覽:702