SpringBoot基礎篇入坑-2

寫在前面:入坑-1階段主要學習了黑馬57期的springboot,覺得還不夠深入,爲了更深入學習springboot,入坑-2階段學習了B站狂神的springboot,特來記錄筆記,源碼部分還是不能很理解,希望下次再來看的時候可以更深入理解。

1. Springboot運行原理

詳見:入坑-1篇3

2. yaml與properties的配置注入

2.1 yaml配置注入

yaml和yml都是springboot推薦的配置,它們的語法一模一樣。

詳見:https://blog.csdn.net/JAYU_37/article/details/105960838
4.1處

yaml配置注入:

  1. @Value注入方式:

    1. Dog類
    @Component
    public class Dog {
        @Value("阿黃")
        private String dname;
        @Value("18")
        private Integer dage;
        .............................
        省略setter和getter方法+toString()
        .............................
    }
    
    1. 測試類:
    @SpringBootTest
    class Spring01KuangFirstApplicationTests {
        @Autowired
        private Dog dog;
    
        @Test
        void contextLoads() {
            System.out.println(dog);
        }
    }
    
    1. 輸出在這裏插入圖片描述
  2. yml注入

    1. Person類
    @Component
    @ConfigurationProperties(prefix = "person")
    public class Person {
        //@Value("${name}")
        private String name;
        private Integer age;
        private Boolean happy;
        private Date birth;
        private Map<String,Object> maps;
        private List<Object> lists;
        private Dog dog;
        .............................
        省略setter和getter方法+toString()
        .............................
        }
    
    
    1. yml配置文件
    #複雜對象 person
    person:
      name: liuzeyu${random.uuid}
      age: 23
      happy: true
      birth: 1998/09/19
      maps:
        hobby: ctrl
        singer: jay
        code: java${random.int}
      lists:
        - eat
        - drink
        - dream
      dog:
        dname: 旺財
        dage: 2
    
    
    
    1. 測試函數
    @SpringBootTest
    class Spring01KuangFirstApplicationTests {
        @Autowired
        private Person person;
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    
    1. 輸出
      在這裏插入圖片描述
    2. 注意:如果在yam或properties中輸入了中問的數據,控制檯打印出亂碼,則在setting中修改配置文件的編碼
      在這裏插入圖片描述

2.2 properties配置注入

  1. 在resources下新建person.properties
    name=kuangshen
    
  2. 在Person類中注入
    在這裏插入圖片描述
  3. 測試函數
    @SpringBootTest
    class Spring01KuangFirstApplicationTests {
        @Autowired
        private Person person;
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    
  4. 輸出
    在這裏插入圖片描述

2.3 yaml與properties的比較

@Value這個用起來並不方便,要爲每一個屬性單獨賦值,太麻煩了,使用於注入參數較少的情況下。
在這裏插入圖片描述
由上圖可知,yaml和properties的區別已經很明顯了

  1. @ConfigurationProperties只需要寫一次就好了,而@Value要寫很多次
  2. 鬆散綁定,例如我們在yml中寫last-name在如果屬性是lastName,也可以注入成功,-後面是大寫字母沒有影響。
  3. JSR303數據校驗,這個就是我們可以在字段上增加一層過濾驗證,來包證數據的合法性。
  4. 複雜類型封裝對象,yml可以封裝對象,使用value就不可以。

2.4 JSR303數據校驗

  1. 爲Person類添加校驗
    在這裏插入圖片描述
  2. 運行結果
    在這裏插入圖片描述
    並且爆出異常,注入失敗!
    使用數據校驗,可以保證數據的正確性;
  3. 常見參數
@NotNull(message="名字不能爲空")
private String userName;
@Max(value=120,message="年齡最大不能查過120")
private int age;
@Email(message="郵箱格式錯誤")
private String email;

空檢查
@Null       驗證對象是否爲null
@NotNull    驗證對象是否不爲null, 無法查檢長度爲0的字符串
@NotBlank   檢查約束字符串是不是Null還有被Trim的長度是否大於0,只對字符串,且會去掉前後空格.
@NotEmpty   檢查約束元素是否爲NULL或者是EMPTY.
    
Booelan檢查
@AssertTrue     驗證 Boolean 對象是否爲 true  
@AssertFalse    驗證 Boolean 對象是否爲 false  
    
長度檢查
@Size(min=, max=) 驗證對象(Array,Collection,Map,String)長度是否在給定的範圍之內  
@Length(min=, max=) string is between min and max included.

日期檢查
@Past       驗證 Date 和 Calendar 對象是否在當前時間之前  
@Future     驗證 Date 和 Calendar 對象是否在當前時間之後  
@Pattern    驗證 String 對象是否符合正則表達式的規則

.......等等
除此以外,我們還可以自定義一些數據校驗規則

3. 自動配置原理

spring的自動配置機制使得我們可以使用官方提供的起步依賴和一些默認值開啓springboot項目,例如springboot內嵌了tomcat服務器,當springboot啓動後,默認使用了8080端口,當然我們也可以修改它,就是新建配置文件去覆蓋默認的配置。
以tomcat的默認端口的自動配置爲例,跟蹤源碼來探探自動配置的原理:

1. springboot啓動時加載主配置類,開啓了@EnableAutoConfiguration

在這裏插入圖片描述
在這裏插入圖片描述

2. @EnableAutoConfiguration的作用是什麼?

利用AutoConfigurationImportSelector給容器導入組件
在這裏插入圖片描述
進入AutoConfigurationImportSelector類

3. 發現獲取組件實體類方法

在這裏插入圖片描述
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);獲取候選配置這個配置就是默認的配置,從哪裏獲取呢繼續進入getCandidateConfigurations方法

4. SpringFactoriesLoader做了什麼?

SpringFactoriesLoader是spring的工廠加載器,負責從工廠創建bean對象加載容器
在這裏插入圖片描述
調用了一個loadFactoryNames,這個此時我們可以猜測加載的這是一個配置文件,而且是一堆全限定類名,通過反射創建對象,繼續查看SpringFactoriesLoader做了什麼?

5. 通過類加載器加載配置文件META-INF/spring.factories

在這裏插入圖片描述

6. META-INF/spring.factories

在這裏插入圖片描述
果然發現一些自動配置類的全限定類名,格式XXXXAutoConfiguration
部分自動配置:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\

找到一個

org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,

進入
ServletWebServerFactoryAutoConfiguration類

7. ServletWebServerFactoryAutoConfiguration

在這裏插入圖片描述
spring的底層註解:根據不同的條件,來判斷當前配置或類是否生效
@ConditionalOnClass:表示的是這是一個什麼類,當前項目由沒有這個類
@ConditionalOnWebApplication:當前項目是不是web項目

常見的ConditionalXXXX
在這裏插入圖片描述

8. 進入ServerProperties類

在這裏插入圖片描述
發現我們熟悉的@ConfigurationProperties,它的作用就是從外界配置文件注入數據到類的屬性中

9.自動配置的過程

看到這裏大致明白了一些自動配置的過程

  1. 從有主類帶註解@EnableAutoConfiguration開始,@EnableAutoConfiguration作用 就是開啓了自動配置功能
  2. springboot啓動類啓動就會去加載factories中的類名,並反射創建對象,但不是全部都有,只有添加了相關依賴jar包的纔有
  3. ServletWebServerFactoryAutoConfiguration所做的事就是創建一些默認的bean存入容器中
  4. 加載我們自定義配置的信息來覆蓋默認的配置,在@EnableConfigurationProperties的屬性中進行,通過屬性綁定的XXXProperties類來產生關聯
  5. XXXAutoConfiguration----> 將默認值封裝成XXXXProperties對象<------->與yml/prorperties綁定
  6. 因此我們可以通過自定義配置yml/prorperties來修改默認的自動配置

10.自動配置的原理

  1. springboot啓動默認會加載大量的自動配置類
  2. 這些自動配置類是否在我們添加的起步依賴jar包中,如果在的話,我們就不用進行手動配置了
  3. 從容器自動配置添加組件(bean)的時候,會從XXXProperties類中獲取某些屬性,我們只需要在配置文件中指定即可

XXXAutoConfiguration:自動配置類,給容器中添加組件
XXXProperties:封裝配置文件中相關的屬性,與spring的配置文件相關聯

11.最後看哪些自動配置類生效了

最後如果想看哪些自動配置ide類生效了,我們可以在配置文件中指定debug = true
例如
在這裏插入圖片描述
不滿足添加的類將不會生效
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

4. springboot靜態資源的位置

4.1 webjars

進入WebMvcAutoConfiguration
閱讀源碼

if (!registry.hasMappingForPattern("/webjars/**")) {
    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

可以通過外部maven座標引入webjars資源目錄

<dependency><!--Jquery組件(前端)-->
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

在這裏插入圖片描述
我們可以通過地址
http://127.0.0.1:8080/webjars/jquery/3.3.1/jquery.js來訪問
其中/META-INF/maven/resources下的目錄就是webjars,也是webjars資源目錄的根目錄。
在這裏插入圖片描述

4.2 其它資源文件的位置

如果使用默認的路徑,即沒有去修改spring.mvc.static-path-pattern則會匹配這裏的路徑

 String staticPathPattern = this.mvcProperties.getStaticPathPattern();
 if (!registry.hasMappingForPattern(staticPathPattern)) {
     this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
 }

進入ResourceProperties的類
發現存放靜態資源對應了下面四個地方

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};

路徑:

"classpath:/META-INF/resources/"   此路徑下就是webjar
"classpath:/resources/", 	//resouces/resouces/資源文件下
"classpath:/static/", 		//resouces/static/資源文件下
"classpath:/public/"		//resouces/public/資源文件下

/** 下的所有資源都會被解析,但是它目錄們四個是具有訪問優先級,resources > static > public,但切記不能直接放在/ 下,即resources下
在這裏插入圖片描述

在這裏插入圖片描述

4.3 小結

springboot中,我們可以使用以下方式處理靜態資源

存放位置:							訪問方式
webjars								http://localhost:8080/webjar/...
/public,/static,/resouces		http://localhost:8080/...

注意:使用/**方式訪問,/public,/static,/**,/resouces具有不一樣的優先級
resources > static > public

5. Thymeleft模板引擎

Thymeleft模板引擎是一個類似於jsp的視圖解析器,但是jsp由於過老,已經被springboot逐漸棄用,springboot更是推薦使用thymeleft
在這裏插入圖片描述
引入問題:
未使用thymeleft前,我們如果想要訪問資源文件下的templates下文件,會出現404將無法訪問,因爲這是springboot官方規定的,必須使用模板引擎才能訪問。

5.1 Thymeleft介紹

5.2 Thymeleft語法

6. MVC自動配置原理

6.1 自定義視圖解析器

手段:通過閱讀官方文檔+源碼的方式理解。(其實不是很理解)

官方文檔:https://docs.spring.io/spring-boot/docs/2.2.7.RELEASE/reference/html/spring-boot-features.html#boot-features-developing-web-applications

7.1.1. Spring MVC Auto-configuration
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.

The auto-configuration adds the following features on top of Spring’s defaults:

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

Support for serving static resources, including support for WebJars (covered later in this document)).

Automatic registration of Converter, GenericConverter, and Formatter beans.

Support for HttpMessageConverters (covered later in this document).

Automatic registration of MessageCodesResolver (covered later in this document).

Static index.html support.

Custom Favicon support (covered later in this document).

Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

翻譯如下

7.1.1。 Spring MVC自動配置
Spring Boot爲Spring MVC提供了自動配置,可與大多數應用程序完美配合。

自動配置在Spring的默認設置之上添加了以下功能:

包含ContentNegotiatingViewResolver和BeanNameViewResolver Bean。

支持服務靜態資源,包括對WebJars的支持(在本文檔的後面部分有介紹)。

自動註冊Converter,GenericConverter和Formatter Bean。

對HttpMessageConverters的支持(在本文檔後面介紹)。

自動註冊MessageCodesResolver(在本文檔後面介紹)。

靜態index.html支持。

自定義Favicon支持(在本文檔後面介紹)。

自動使用ConfigurableWebBindingInitializer Bean(在本文檔後面介紹)。

如果要保留這些Spring Boot MVC定製並進行更多的MVC定製(攔截器,格式化程序,視圖控制器和其他功能),則可以添加自己的類型爲WebMvcConfigurer的@Configuration類,但不添加@EnableWebMvc。

如果要提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定義實例,並且仍然保留Spring Boot MVC自定義,則可以聲明WebMvcRegistrations類型的Bean,並使用它提供這些組件的自定義實例。

如果要完全控制Spring MVC,則可以添加用@EnableWebMvc註釋的自己的@Configuration,或者按照@EnableWebMvc的Javadoc中的說明添加自己的@Configuration註釋的DelegatingWebMvcConfiguration。

抓住這兩個主要的類:

ContentNegotiatingViewResolver和BeanNameViewResolver Bean。
  1. 先進入WebMvcAutoConfiguration ,之後按住CTRL+shift+alt+N進入全局搜索ContentNegotiatingViewResolver
public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered, InitializingBean {
    @Nullable
    private ContentNegotiationManager contentNegotiationManager;
    private final ContentNegotiationManagerFactoryBean cnmFactoryBean = new ContentNegotiationManagerFactoryBean();
    private boolean useNotAcceptableStatusCode = false;
    @Nullable
    private List<View> defaultViews;
    @Nullable
    private List<ViewResolver> viewResolvers;
    private int order = -2147483648;
    private static final View NOT_ACCEPTABLE_VIEW = new View() {
        @Nullable
        public String getContentType() {
            return null;
        }

        public void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) {
            response.setStatus(406);
        }
    };

    public ContentNegotiatingViewResolver() {
    }
......................
  1. 找到對應的解析視圖的代碼
    在這裏插入圖片描述

  2. getCandidateViews是如何獲取它的候選視圖解析器
    Iterator var5 = this.viewResolvers.iterator();
    在這裏插入圖片描述
    因此得出結論:ContentNegotiatingViewResolver視圖解析器是用來組合所有的視圖解析器的。
    此時我們可以查看viewResolvers的值是哪裏來的,CTRL+f搜索
    在這裏插入圖片描述

  3. 是從IOC容器中獲取的,於是我們可以猜測,是否可以自定義視圖解析器呢?
    答案是可以的,根據官方文檔的說法:

    如果要保留這些Spring Boot MVC定製並進行更多的MVC定製(攔截器,格式化程序,視圖控制器和其他功能),則可以添加自己的類型爲WebMvcConfigurer的@Configuration類,但不添加@EnableWebMvc

  4. 於是自定義如下:

@Configuration
public class MyMvcConfig  implements WebMvcConfigurer {

    //MyVieResolver就是一個視圖解析器加入容器中
    @Bean
    public ViewResolver setMyVieResolver(){
        return new MyVieResolver();
    }

    //自定義一個自己的視圖解析器MyVieResolver
    private static class MyVieResolver implements ViewResolver{
        @Override
        public View resolveViewName(String s, Locale locale) throws Exception {
            return null;
        }
    }
}

如何驗證是否加入容器成功呢?
6. 我們給 DispatcherServlet 中的 doDispatch方法 加個斷點進行調試一下,因爲所有的請求都會走到這個方法中
在這裏插入圖片描述
發現了我們自己添加進去的ViewResolver
在這裏插入圖片描述
沒有添加之前默認只是5個
在這裏插入圖片描述
ContentNegotiatingViewResolver使用所有其他視圖解析器來定位視圖,因此它應該具有較高的優先級

6.2 擴展springMVC

修改springboot默認配置,通過閱讀上面的官方文檔

如果要保留這些Spring Boot MVC定製並進行更多的MVC定製(攔截器,格式化程序,視圖控制器和其他功能),則可以添加自己的類型爲WebMvcConfigurer的@Configuration類,但不添加@EnableWebMvc

我們要做的事創建一個配置類,放在包config下,實現WebMvcConfigurer接口,但是不能添加@EnableWebMvc

@Configuration
public class ExtendsMvc implements WebMvcConfigurer {

    //方法的作用是添加視圖的控制跳轉
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/liu").setViewName("index");
    }
}

訪問成功
在這裏插入圖片描述
這就是官方推薦我們使用的擴展方法,即保留課springboot的原有配置,也擴展了我們想要的配置。
我們來分析一些內部的原理

  1. WebMvcAutoConfiguration是springMVC的自動配置類,它有一個內部類WebMvcAutoConfigurationAdapter,作用則是去適配springMVC的各種組件。
  2. 進來查看WebMvcAutoConfigurationAdapter類,發現被導入了一個配置
    @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
  3. 進EnableWebMvcConfiguration類查看,發現這是一個靜態內部類
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration,並且繼承了DelegatingWebMvcConfiguration

它的父類DelegatingWebMvcConfiguration有一個這樣的方法setConfigurers
在這裏插入圖片描述
這個方法的作用是從容器中獲取所有的configurers
在這裏插入圖片描述
進入addViewControllers方法
在這裏插入圖片描述
將所有的WebMvcConfigurer相關配置來一起調用!包括我們自己配置的和Spring給我們配置的
所以我們得出結論:所有的WebMvcConfiguration被作用,不止spring自己的配置類,我們自定義的也會被調用。

6.3 全面接管SpringMVC

所謂的全面接管SpringMVC,則是在配置類上使用@EnableWebMvc
作用則是springboot對springmvc的所有自動配置失效,由我們自己配置springmvc
不加@EnableWebMvc
在這裏插入圖片描述
加@EnableWebMvc
在這裏插入圖片描述
可見所有的springMVC配置全部都失效了,但實際開發中,我們並不推薦全面接管springMVC。
爲什麼說加上@EnableWebMvc所有配置就失效 了呢
閱讀源碼:

  1. 進入@EnableWebMvc
    在這裏插入圖片描述
    EnableWebMvc導入了一個配置類DelegatingWebMvcConfiguration
  2. 進入DelegatingWebMvcConfiguration
    在這裏插入圖片描述
    DelegatingWebMvcConfiguration繼承了一個WebMvcConfigurationSupport
  3. 進入springMVC自動配置類WebMvcAutoConfiguration,發現了
    在這裏插入圖片描述
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})的作用:如果不是WebMvcConfigurationSupport類,則自動配置類生效
  4. 顯然我們EnableWebMvc導入了WebMvcConfigurationSupport的子類,於是DelegatingWebMvcConfiguration也是屬於WebMvcConfigurationSupport,故自動配置類就失效了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章