日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

MVC自动配置原理---SpringBoot

發(fā)布時間:2023/12/3 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MVC自动配置原理---SpringBoot 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MVC自動配置原理

官網閱讀

在進行項目編寫前,我們還需要知道一個東西,就是SpringBoot對我們的SpringMVC還做了哪些配置,包括如何擴展,如何定制。

只有把這些都搞清楚了,我們在之后使用才會更加得心應手。途徑一:源碼分析,途徑二:官方文檔!

地址 :https://docs.spring.io/spring-boot/docs/2.4.1.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration

Spring MVC Auto-configuration // Spring Boot為Spring MVC提供了自動配置,它可以很好地與大多數(shù)應用程序一起工作。 Spring Boot provides auto-configuration for Spring MVC that works well with most applications. // 自動配置在Spring默認設置的基礎上添加了以下功能: The auto-configuration adds the following features on top of Spring’s defaults: // 包含視圖解析器 Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans. // 支持靜態(tài)資源文件夾的路徑,以及webjars Support for serving static resources, including support for WebJars // 自動注冊了Converter: // 轉換器,這就是我們網頁提交數(shù)據(jù)到后臺自動封裝成為對象的東西,比如把"1"字符串自動轉換為int類型 // Formatter:【格式化器,比如頁面給我們了一個2019-8-10,它會給我們自動格式化為Date對象】 Automatic registration of Converter, GenericConverter, and Formatter beans. // HttpMessageConverters // SpringMVC用來轉換Http請求和響應的的,比如我們要把一個User對象轉換為JSON字符串,可以去看官網文檔解釋; Support for HttpMessageConverters (covered later in this document). // 定義錯誤代碼生成規(guī)則的 Automatic registration of MessageCodesResolver (covered later in this document). // 首頁定制 Static index.html support. // 圖標定制 Custom Favicon support (covered later in this document). // 初始化數(shù)據(jù)綁定器:幫我們把請求數(shù)據(jù)綁定到JavaBean中! Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document)./* 如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(攔截器、格式化程序、視圖控制器和其他功能),則可以添加自己 的@configuration類,類型為webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供 RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定義 實例,則可以聲明WebMVCregistrationAdapter實例來提供此類組件。 */ If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc進行注釋。 If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

我們來仔細對照,看一下它怎么實現(xiàn)的,它告訴我們SpringBoot已經幫我們自動配置好了SpringMVC,然后自動配置了哪些東西呢?

ContentNegotiatingViewResolver 內容協(xié)商視圖解析器

自動配置了ViewResolver,就是我們之前學習的SpringMVC的視圖解析器;

即根據(jù)方法的返回值取得視圖對象(View),然后由視圖對象決定如何渲染(轉發(fā),重定向)。

我們去看看這里的源碼:我們找到 WebMvcAutoConfiguration , 然后搜索ContentNegotiatingViewResolver。找到如下方法!

@Bean @ConditionalOnBean(ViewResolver.class) @ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class) public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setContentNegotiationManager(beanFactory.getBean(ContentNegotiationManager.class));// ContentNegotiatingViewResolver使用所有其他視圖解析器來定位視圖,因此它應該具有較高的優(yōu)先級resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);return resolver; }

我們可以點進這類看看!找到對應的解析視圖的代碼;

@Nullable // 注解說明:@Nullable 即參數(shù)可為null public View resolveViewName(String viewName, Locale locale) throws Exception {RequestAttributes attrs = RequestContextHolder.getRequestAttributes();Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());if (requestedMediaTypes != null) {// 獲取候選的視圖對象List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);// 選擇一個最適合的視圖對象,然后把這個對象返回View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);if (bestView != null) {return bestView;}}// ..... }

我們繼續(xù)點進去看,他是怎么獲得候選的視圖的呢?

getCandidateViews中看到他是把所有的視圖解析器拿來,進行while循環(huán),挨個解析!

Iterator var5 = this.viewResolvers.iterator();

所以得出結論:ContentNegotiatingViewResolver 這個視圖解析器就是用來組合所有的視圖解析器的

我們再去研究下他的組合邏輯,看到有個屬性viewResolvers,看看它是在哪里進行賦值的!

protected void initServletContext(ServletContext servletContext) {// 這里它是從beanFactory工具中獲取容器中的所有視圖解析器// ViewRescolver.class 把所有的視圖解析器來組合的Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();ViewResolver viewResolver;if (this.viewResolvers == null) {this.viewResolvers = new ArrayList(matchingBeans.size());}// ............... }

既然它是在容器中去找視圖解析器,我們是否可以猜想,我們就可以去實現(xiàn)一個視圖解析器了呢?

我們可以自己給容器中去添加一個視圖解析器;這個類就會幫我們自動的將它組合進來;我們去實現(xiàn)一下

1、我們在我們的主程序中去寫一個視圖解析器來試試;

@Bean //放到bean中public ViewResolver myViewResolver(){ return new MyViewResolver();} //我們寫一個靜態(tài)內部類,視圖解析器就需要實現(xiàn)ViewResolver接口private static class MyViewResolver implements ViewResolver{ @Override public View resolveViewName(String s, Locale locale) throws Exception { return null; }}

2、怎么看我們自己寫的視圖解析器有沒有起作用呢?

我們給 DispatcherServlet 中的 doDispatch方法 加個斷點進行調試一下,因為所有的請求都會走到這個方法中

3、我們啟動我們的項目,然后隨便訪問一個頁面,看一下Debug信息;

找到this

找到視圖解析器,我們看到我們自己定義的就在這里了;

所以說,我們如果想要使用自己定制化的東西,我們只需要給容器中添加這個組件就好了!剩下的事情SpringBoot就會幫我們做了!

轉換器和格式化器

找到格式化轉換器:

@Bean @Override public FormattingConversionService mvcConversionService() {// 拿到配置文件中的格式化規(guī)則WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());addFormatters(conversionService);return conversionService; }

點擊去:

public String getDateFormat() { return this.dateFormat; } /*** Date format to use. For instance, `dd/MM/yyyy`. 默認的 */ private String dateFormat;

可以看到在我們的Properties文件中,我們可以進行自動配置它!

如果配置了自己的格式化方式,就會注冊到Bean中生效,我們可以在配置文件中配置日期格式化的規(guī)則:

修改SpringBoot的默認配置

這么多的自動配置,原理都是一樣的,通過這個WebMVC的自動配置原理分析,我們要學會一種學習方式,通過源碼探究,得出結論;這個結論一定是屬于自己的,而且一通百通。

SpringBoot的底層,大量用到了這些設計細節(jié)思想,所以,沒事需要多閱讀源碼!得出結論;

SpringBoot在自動配置很多組件的時候,先看容器中有沒有用戶自己配置的(如果用戶自己配置@bean),如果有就用用戶配置的,如果沒有就用自動配置的;

如果有些組件可以存在多個,比如我們的視圖解析器,就將用戶配置的和自己默認的組合起來!

擴展使用SpringMVC 官方文檔如下:

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

我們要做的就是編寫一個@Configuration注解類,并且類型要為WebMvcConfigurer,還不能標注@EnableWebMvc注解;我們去自己寫一個;我們新建一個包叫config,寫一個類MyMvcConfig;

//應為類型要求為WebMvcConfigurer,所以我們實現(xiàn)其接口 //可以使用自定義類擴展MVC的功能 @Configuration public class MyMvcConfig implements WebMvcConfigurer {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {// 瀏覽器發(fā)送/test , 就會跳轉到test頁面;registry.addViewController("/test").setViewName("test");} }

我們去瀏覽器訪問一下:

確實也跳轉過來了!所以說,我們要擴展SpringMVC,官方就推薦我們這么去使用,既保SpringBoot留所有的自動配置,也能用我們擴展的配置!

我們可以去分析一下原理:

1、WebMvcAutoConfiguration 是 SpringMVC的自動配置類,里面有一個類WebMvcAutoConfigurationAdapter

2、這個類上有一個注解,在做其他自動配置時會導入:@Import(EnableWebMvcConfiguration.class)

3、我們點進EnableWebMvcConfiguration這個類看一下,它繼承了一個父類:DelegatingWebMvcConfiguration

這個父類中有這樣一段代碼:

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();// 從容器中獲取所有的webmvcConfigurer@Autowired(required = false)public void setConfigurers(List<WebMvcConfigurer> configurers) {if (!CollectionUtils.isEmpty(configurers)) {this.configurers.addWebMvcConfigurers(configurers);}} }

4、我們可以在這個類中去尋找一個我們剛才設置的viewController當做參考,發(fā)現(xiàn)它調用了一個

protected void addViewControllers(ViewControllerRegistry registry) {this.configurers.addViewControllers(registry); }

5、我們點進去看一下

public void addViewControllers(ViewControllerRegistry registry) {Iterator var2 = this.delegates.iterator();while(var2.hasNext()) {// 將所有的WebMvcConfigurer相關配置來一起調用!包括我們自己配置的和Spring給我們配置的WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();delegate.addViewControllers(registry);}}

所以得出結論:所有的WebMvcConfiguration都會被作用,不止Spring自己的配置類,我們自己的配置類當然也會被調用;

全面接管SpringMVC

官方文檔:

If you want to take complete control of Spring MVCyou can add your own @Configuration annotated with @EnableWebMvc.

全面接管即:SpringBoot對SpringMVC的自動配置不需要了,所有都是我們自己去配置!

只需在我們的配置類中要加一個@EnableWebMvc。

我們看下如果我們全面接管了SpringMVC了,我們之前SpringBoot給我們配置的靜態(tài)資源映射一定會無效,我們可以去測試一下;

不加注解之前,訪問首頁:

給配置類加上注解:@EnableWebMvc

我們發(fā)現(xiàn)所有的SpringMVC自動配置都失效了!回歸到了最初的樣子;

當然,我們開發(fā)中,不推薦使用全面接管SpringMVC

思考問題?為什么加了一個注解,自動配置就失效了!我們看下源碼:

1、這里發(fā)現(xiàn)它是導入了一個類,我們可以繼續(xù)進去看

@Import({DelegatingWebMvcConfiguration.class})public @interface EnableWebMvc {}

2、它繼承了一個父類 WebMvcConfigurationSupport

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { // ......}

3、我們來回顧一下Webmvc自動配置類

@Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) // 這個注解的意思就是:容器中沒有這個組件的時候,這個自動配置類才生效 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration {}

總結一句話:@EnableWebMvc將WebMvcConfigurationSupport組件導入進來了;

而導入的WebMvcConfigurationSupport只是SpringMVC最基本的功能!

在SpringBoot中會有非常多的擴展配置,只要看見了這個,我們就應該多留心注意~

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結

以上是生活随笔為你收集整理的MVC自动配置原理---SpringBoot的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。