天天看點

Spring Boot 自動配置及通路靜态資源原理

一、自動配置

Spring Boot 啟動類上有個注解: @SpringBootApplication,其實這是一個組合注解,由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan組成。

Spring Boot 自動配置及通路靜态資源原理

@SpringBootConfiguration其實可以認為是@Configuration的一個更新版版,用來差別spring framework 和 spring boot的,而@ComponentScan在spring framework就支援的,是以重點關注@EnableAutoConfiguration,

可以看到這個注解引入了AutoConfigurationImportSelector和@AutoConfigurationPackage

Spring Boot 自動配置及通路靜态資源原理

這裡關注AutoConfigurationImportSelector,他實作了N多類,如下:

Spring Boot 自動配置及通路靜态資源原理

其中需要關注的是DeferredImportSelector,他繼承了ImportSelector,然後在spring初始化過程中會調用到,具體看圖:

Spring Boot 自動配置及通路靜态資源原理

隻要斷點在org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry中,就可以看到上圖中的調用過程。

下面列舉一下上圖中主要的幾個環節:

org.springframework.boot.SpringApplication#run()  ->
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors()  ->
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions()  ->
org.springframework.context.annotation.ConfigurationClassParser#parse()  -> 
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process()  ->
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports()  ->
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports()  ->
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process()  ->
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry()      

重點看getAutoConfigurationEntry中做了什麼事:

Spring Boot 自動配置及通路靜态資源原理

經過一番操作,剩下23個自動配置類:

org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration      

到這裡基本上就能看明白自動配置是怎麼回事了。

二、通路靜态資源

如下:resources/static/ 目錄下有個index.html,沒有在代碼中手動配置的情況下,直接通路http://localhost:8080/ ,可以看到跳轉到了index.html,這是為什麼?

Spring Boot 自動配置及通路靜态資源原理

原來在org.springframework.boot.autoconfigure.web.ResourceProperties中定義了一個屬性,這個屬性指定了預設的CLASSPATH_RESOURCE_LOCATIONS,如下:

Spring Boot 自動配置及通路靜态資源原理

在講自動配置的時候,剩下的23個自動配置類中有個org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,在這個類中,spring boot做了與spring mvc相關的一些預設配置,在應用啟動過程中擷取歡迎頁面時,會調用org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#getWelcomePage,可以看到正好取到了上面配置的四個預設路徑,如下:

Spring Boot 自動配置及通路靜态資源原理

正因為spring boot 預設設定了資源路徑,是以可以在不手動配置的情況下就能通路index.html。

如果将/static/ 從預設配置中去掉,再通路頁面時,會看到報錯,如下:

Spring Boot 自動配置及通路靜态資源原理

說白了,spring boot 的這種預設配置就類似于配置了視圖解析器和(或)資源映射器,如果開發人員想通路自定義頁面,那麼可以做如下配置:

package org.springframework.boot.francis.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@EnableWebMvc
@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("classpath:/page/", ".html");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("classpath:/page/**")
                .addResourceLocations("classpath:/page/");
    }
}      

效果如下:

Spring Boot 自動配置及通路靜态資源原理

繼續閱讀