其實在之前的筆記中,有記錄過handlerAdapter、handlerMapping初始化的一些細節,但是前幾天在寫策略模式那篇筆記的時候,突然間想到一個問題,RequestMappingHandlerAdapter、RequestMappingHandlerMapping是在什么時候放入到beanDefinitionMap中的
今天這篇筆記主要記錄下這里是如何放入到beanDefinitionMap中這個問題
其實這篇筆記也可以理解為springboot專案和傳統的springmvc專案有什么區別
結論
簡單來說:在EnableWebMvcConfiguration中,通過@Bean來完成的
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final WebMvcRegistrations mvcRegistrations;
public EnableWebMvcConfiguration(
ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider,
ListableBeanFactory beanFactory) {
this.mvcProperties = mvcPropertiesProvider.getIfAvailable();
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties != null
? this.mvcProperties.isIgnoreDefaultModelOnRedirect() : true);
return adapter;
}
@Override
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
if (this.mvcRegistrations != null
&& this.mvcRegistrations.getRequestMappingHandlerAdapter() != null) {
return this.mvcRegistrations.getRequestMappingHandlerAdapter();
}
return super.createRequestMappingHandlerAdapter();
}
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
if (this.mvcRegistrations != null
&& this.mvcRegistrations.getRequestMappingHandlerMapping() != null) {
return this.mvcRegistrations.getRequestMappingHandlerMapping();
}
return super.createRequestMappingHandlerMapping();
}
}
這里我刪減了部分代碼,可以看到,在這個類中,通過@Bean宣告了handlerMapping和handlerAdapter,這是對于springboot專案來說的
那EnableWebMvcConfiguration是在什么時候被初始化的?或者說是如何被spring所掃描到的?我們實際在代碼中會發現,EnableMvcConfiguration是WebMvcAutoConfiguration的一個內部類,而WebMvcAutoConfiguration是通過springboot的自動配置來完成的,在springboot-autoconfigure.jar包的spring.factories檔案中有配置該bean
springmvc專案是如何初始化handlerMapping的?
那非springboot專案呢?如果我的專案就是一個傳統的springmvc專案,非springboot專案,沒有自動注入的功能,那怎么辦?其實很簡單,既然傳統的springmvc專案沒有自動注入,那我程式員就自己去注入,通過@EnableWebMvc這個注解;
@EnableWebMvc注解通過@Import引入了一個類DelegatingWebMvcConfiguration
在DelegatingWebMvcConfiguration中,并沒有對handlerMapping的處理,但是在其父類中:WebMvcConfigurationSupport
通過@Bean去定義了handlerMapping和handlerAdapter,所以,對于springmvc專案來說,也是通過@Bean這種形式來宣告handlerMapping的,只是和springboot專案相比,時機不同而已,但是底層的原理都是一樣的
其實說到這個點,最近有一個反思,學習一個框架,先要學習底層的思想,而上層的框架,無非就是在底層的擴展點上翻來覆去的使用,spring、springboot、springmvc這三個框架,在看原始碼的時候,深有體會;也就是說,在看springboot的原始碼的時候,需要先了解spring底層的原始碼,因為在springboot中,很多很多點,都是通過spring底層的一個擴展點或者是底層邏輯來實作的,那這樣,在看springboot原始碼的時候,就能比較快的連貫起來,否則的話,那我們想下,看到springboot的一個點,去學習下spring的原理,那這樣的話,等學會了spring這個點的原理,再反過來去看springboot的時候,就可能連貫不起來了
通過@Bean,宣告了handlerMapping和handlerAdapter之后,那其他的事情,就不需要springmvc去處理了,spring底層會幫我們去初始化、實體化等等
所以,spring原始碼看的多了,就會發現,底層的一些思想,真的是很值得去學習的,不知道該怎么去表達,總之,原始碼在看起來是比較難得,但是越往后學習,原始碼學起來越快,因為前面說了,思想是基本上一樣的
說到這里了,再扯點其他的,在沒有看spring官方檔案之前,或者說從上大學開始,對于spring、springmvc我一直認為是兩個專案,或者說我認為springmvc是在spring基礎之上的一個提升
但是,實際去看下官方檔案,springmvc只是spring的一部分,我們通常所說的spring,就是spring framework,而在官方檔案中,springmvc只是spring framework的一個章節

至于我們常說的IOC、AOP、el運算式,是spring framework中的core這個章節的一部分
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/283049.html
標籤:其他
