日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

全網最深分析SpringBoot MVC自動配置失效的原因

瀏覽:71日期:2023-05-08 08:52:26

前言

本來沒有計劃這一篇文章的,只是在看完SpringBoot核心原理后,突然想到之前開發中遇到的MVC自動失效的問題,雖然網上有很多文章以及官方文檔都說明了原因,但還是想親自看一看,本以為很簡單的事情,沒想到卻引發出一個較復雜的問題,請教了很多人都沒有得到結果,網上文章也沒有寫清楚的,最后還是自己搞了很久才弄明白的,此篇主要記錄自己的一個分析過程。

正文

引出問題

全網最深分析SpringBoot MVC自動配置失效的原因

上面是SpringBoot MVC的自動配置,問題是這樣的,當我們需要自己配置MVC時,有三種選擇:

實現WebMvcConfigurer接口 繼承WebMvcConfigurerAdapter類 繼承WebMvcConfigurationSupport類

在老版本中我們常用的做法就是繼承WebMvcConfigurerAdapter類,這個類本身是實現了WebMvcConfigurer接口的,因為老版本JDK接口沒有默認方法,直接實現WebMvcConfigurer比較繁瑣,而后來接口可以有默認方法了,WebMvcConfigurerAdapter就被標記為過時了,所以我們現在配置MVC只需要實現WebMvcConfigurer接口或者繼承WebMvcConfigurationSupport,但是后者會導致SpringBoot的配置失效,因為在自動配置類上有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)這樣一個注解,表示沒有WebMvcConfigurationSupport類及其子類的實例時才會加載自動配置(另外使用@EnableWebMvc注解也會導致自動配置失效)。

MVC自動配置失效的原因就是這個了,基本上所有網上的文章分析到這一步也就完了,但是注意上圖我畫的紅方框,在這個自動配置類中有兩個靜態內部類,我們知道靜態內部類是優于外部類加載的(SpringBoot自動配置大量使用了此特性),而其中EnableWebMvcConfiguration這個類,我注意到它是繼承自DelegatingWebMvcConfiguration,而DelegatingWebMvcConfiguration又繼承自WebMvcConfigurationSupport類,相信看到這你也應該會有疑惑了,為什么這個配置類沒有導致自動配置失效,而我們自己實現的就會?

分析過程

我知道配置類的解析注冊是在ConfigurationClassPostProcessor類中,而這個類我前面的文章多次分析過,雖然這個類的實現流程不難,但細節非常繞,所以之前沒有深挖。遇到這個問題時,我首先想的是對這個類的理解不夠深刻,因此第一時間想到仔細研究這個類,在花費了大量時間斷點分析后,卻沒有太大的收獲。

接著我又想,是不是配置類的注冊順序在自動配置的后面。這里我就犯了一個顯而易見的錯誤,因為我考慮的是注冊的順序,不是實例化。因為ConditionalOnMissingBean注解是沒有指定bean的實例時才會去加載,而我腦海里當時想成了ConditionalOnMissingClass。所以我在DefaultListableBeanFactory中的registerBeanDefinition和preInstantiateSingletons方法上打上了斷點,力圖確認注冊順序如我所想:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {....this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}}public void preInstantiateSingletons() throws BeansException {List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);....}

全網最深分析SpringBoot MVC自動配置失效的原因

但結果beanDefinitionNames中的順序卻是兩個靜態內部類在前,也就是說靜態內部類肯定是在外部類之前就注冊到IOC容器中了,這下我就傻了。但幸好也是因此,否則我就該認為這就是結果了。最終我想到了應該看類的實例化順序,但是正常情況下類的實例化順序就是上面的斷點圖中的順序,我想會不會是有什么類依賴了WebMvcAutoConfiguration,導致它提前實例化。于是我將斷點又設置到AbstractBeanFactory中的doGetBean方法并加上了條件(不得不說idea的功能非常強大,回到上一個調用點、給斷點設置條件、調用堆棧信息大大節省了我的調試時間):

全網最深分析SpringBoot MVC自動配置失效的原因

然后啟動項目就可以看到首先實例化的果然是WebMvcAutoConfiguration類,這樣就搞清楚了為什么EnableWebMvcConfiguration沒有導致自動配置失效。

但是還沒完,為什么自動配置類會在靜態內部類之前實例化呢?是由誰觸發的呢?繼續深入,這時我想到了看調用棧:

全網最深分析SpringBoot MVC自動配置失效的原因

粗略看一下調用棧信息,如果對Spring源碼熟悉,可以發現自動配置類的實例化是在instantiateUsingFactoryMethod中觸發的:

String factoryBeanName = mbd.getFactoryBeanName();if (factoryBeanName != null) {if (factoryBeanName.equals(beanName)) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,'factory-bean reference points back to the same bean definition');}factoryBean = this.beanFactory.getBean(factoryBeanName);if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {throw new ImplicitlyAppearedSingletonException();}factoryClass = factoryBean.getClass();isStatic = false;}else {// It’s a static factory method on the bean class.if (!mbd.hasBeanClass()) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,'bean definition declares neither a bean class nor a factory-bean reference');}factoryBean = null;factoryClass = mbd.getBeanClass();isStatic = true;}

這段代碼在bean實例化的那一篇分析過,這個方法的作用是通過factoryMethod實例化當前的BeanDefinition,而實例化該BD優先會實例化factoryBeanName屬性指向的Bean,這里的factoryBeanName就是org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,factoryMethod則是formContentFilter,而這兩個屬性的設置則是在ConfigurationClassPostProcessor解析@Configuration和@Bean就設置好了(@Bean標注的方法名會設置到factoryMethod,而該方法所在配置類的名稱就是factoryBeanName),這里就不展開分析了。

@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 {public static final String DEFAULT_PREFIX = '';public static final String DEFAULT_SUFFIX = '';private static final String[] SERVLET_LOCATIONS = { '/' };@Bean@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)@ConditionalOnProperty(prefix = 'spring.mvc.hiddenmethod.filter', name = 'enabled', matchIfMissing = false)public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();}@Bean@ConditionalOnMissingBean(FormContentFilter.class)@ConditionalOnProperty(prefix = 'spring.mvc.formcontent.filter', name = 'enabled', matchIfMissing = true)public OrderedFormContentFilter formContentFilter() {return new OrderedFormContentFilter();}......}

formContentFilter就是在MVC自動配置類中配置的,默認是加載的,而filter就不用多說了,在Tomcat啟動后就會觸發初始化,追蹤調用棧也可以看到。另外我們還看到自動配置類中還配置了一個HiddenHttpMethodFilter,不過這個默認是不加載的,所以我們只要在application.properties中配置了如下屬性,自動配置類就不會實例化了,但是兩個靜態內部類的實例化還是不會受影響的。

spring.mvc.formcontent.filter.enabled=false

總結

該問題只是出于興趣研究,雖然耗費了大量的時間和精力,但收獲不少,加深了對Spring源碼的理解,也修正了之前的一些錯誤理解,另外對于源碼更多的是要自己去研究,不能只看一兩篇文章或聽別人說,只有自己親手調試過才能知道自己的理解是否正確。

到此這篇關于全網最深分析SpringBoot MVC自動配置失效的原因的文章就介紹到這了,更多相關SpringBoot MVC自動配置失效內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品亚洲二区| 奇米亚洲欧美| 99精品在线观看| 欧美日韩国产一区精品一区| 综合视频一区| 国产精品第十页| 日韩中文欧美| 综合色就爱涩涩涩综合婷婷| 国产精品对白久久久久粗| 精品捆绑调教一区二区三区| 久久亚洲欧洲| 精品视频一区二区三区四区五区 | 偷拍亚洲精品| 精品理论电影在线| 黄色成人91| 久久国产欧美日韩精品| 日韩精品久久久久久久电影99爱| 免费观看在线色综合| 精品视频在线观看网站| 国产视频一区在线观看一区免费| 国产乱码精品一区二区三区亚洲人| 久久久精品五月天| 日韩国产精品久久久久久亚洲| 精品视频91| 99国内精品| 久久99蜜桃| 亚洲免费播放| 精品入口麻豆88视频| 午夜在线视频观看日韩17c| 久久99高清| 日韩午夜视频在线| 91精品国产乱码久久久久久久| 国产欧美一区二区三区米奇| 成人精品亚洲| 国产高清亚洲| 蜜臀a∨国产成人精品| 国产成人精选| 欧美中文高清| 首页欧美精品中文字幕| 福利一区二区免费视频| 日韩在线电影| 中文字幕系列一区| 国产精品久久国产愉拍| 久久一二三区| 久久久久欧美精品| 精品久久久久久久| 欧美一区二区三区久久精品| 亚洲色诱最新| 中文另类视频| 久久中文字幕一区二区| 日韩精品成人| 亚洲一区二区三区免费在线观看| 超碰在线99| 国产精品久久久亚洲一区| 欧美专区一区二区三区| av在线资源| 国产精品分类| 欧美在线观看天堂一区二区三区| 日韩在线一二三区| 国产一区视频在线观看免费| 成人在线视频免费| 久久影院一区二区三区| 国产日产精品_国产精品毛片 | 亚洲在线电影| 色老板在线视频一区二区| 精品一区二区三区免费看 | 午夜久久影院| 日韩一区二区中文| 精品视频亚洲| 国产精品**亚洲精品| 欧美日韩一视频区二区| 中文字幕免费一区二区| 美女被久久久| 99国产精品自拍| 亚洲高清激情| 欧洲亚洲一区二区三区| 久久99高清| 精品视频在线观看网站| 麻豆精品在线视频| 国产精品videossex久久发布| 亚洲图片久久| 中文字幕免费精品| 蜜臀91精品一区二区三区| 亚洲激情精品| 国产亚洲精品v| 一区二区视频欧美| 国产精品日韩| 国产精品呻吟| 男人天堂欧美日韩| 免费看精品久久片| 亚洲+小说+欧美+激情+另类| 偷拍亚洲精品| 日韩精品一区二区三区中文 | 日韩av中文字幕一区二区三区| 五月亚洲婷婷| 欧美另类中文字幕| 国产欧美日韩在线一区二区| 日本不卡不码高清免费观看| 日本欧美久久久久免费播放网| 日韩视频一二区| 日韩av一区二区三区| 国产亚洲精品美女久久| 国产欧美大片| 久久精品毛片| 水蜜桃久久夜色精品一区| 日韩欧美在线中字| 九九综合九九| 视频一区视频二区中文字幕| 亚洲精品少妇| 久久国产精品美女| 久久久久久婷| 日韩欧美一区二区三区在线观看 | 涩涩av在线| 亚洲午夜久久久久久尤物| 黄色免费成人| 日韩精品一区二区三区av | 午夜亚洲精品| 日韩精品乱码av一区二区| 国产精品主播| 高潮久久久久久久久久久久久久| 日韩精品一二三区| 精品五月天堂| 欧美男人天堂| 久久天堂精品| 视频福利一区| 婷婷综合五月| 香蕉久久夜色精品国产| 影院欧美亚洲| 911精品国产| 亚洲国产福利| 噜噜噜躁狠狠躁狠狠精品视频| 日本亚洲最大的色成网站www| 亚洲1区在线观看| 久久伊人国产| 欧美日韩国产亚洲一区| 欧美日韩va| 亚洲精品88| 在线亚洲观看| 国产精品黄色| 日韩视频二区| 午夜精品成人av| 国产成人精品亚洲线观看| 欧洲亚洲一区二区三区| 欧美午夜不卡影院在线观看完整版免费| 午夜视频精品| 日韩精品福利一区二区三区| 国产精品一区二区三区美女| 免费观看亚洲| 亚洲深爱激情| 麻豆精品新av中文字幕| 激情欧美国产欧美| 欧美一区二区三区久久精品| 日韩精品不卡一区二区| 久热综合在线亚洲精品| 国产66精品| 亚洲精品第一| 日本欧美不卡| 奇米色欧美一区二区三区| 欧美精品高清| 久久精品97| 欧美日韩国产一区二区三区不卡| 日韩国产一二三区| 久久久久免费av| 日本午夜精品| 午夜久久黄色| 成人午夜网址| 日韩有吗在线观看| 久久影院一区| 欧美激情一区| 免费的成人av| 日本欧美不卡| 免费在线欧美黄色| 亚洲视频二区| 久久国产影院| 美女毛片一区二区三区四区最新中文字幕亚洲| 亚洲激情不卡| 婷婷激情一区| 国产精品片aa在线观看| 亚洲一区二区三区四区五区午夜 | 日韩高清一区二区| 午夜久久免费观看| 红杏一区二区三区| 日韩av影院| 久久福利影视| 久久免费黄色| 久久99视频| 日韩激情一二三区| 9色精品在线| 亚洲成人av观看| 国产精品综合| 亚洲精品中文字幕99999| 悠悠资源网久久精品| 久久久久国产精品一区二区| 国内精品美女在线观看| 亚洲三级精品| 伊人精品在线| 激情欧美日韩一区| 国产精品s色| 亚洲综合精品四区| 日韩欧美午夜|