詳解Springboot,spring,springMVC 的關係

本文原文轉自 https://blog.csdn.net/hang1995/article/details/84330295css

spring boot就是一個大框架裏面包含了許許多多的東西,其中spring就是最核心的內容之一,固然就包含spring mvc。spring mvc 是隻是spring 處理web層請求的一個模塊。所以他們的關係大概就是這樣:spring mvc  < spring <springboot。html

理清SpringBoot與SpringMVC的關係java

Spring 框架就像一個家族,有衆多衍生產品例如 boot、security、jpa等等。但他們的基礎都是Spring 的 ioc和 aop ioc 提供了依賴注入的容器 aop ,解決了面向橫切面的編程,而後在此二者的基礎上實現了其餘延伸產品的高級功能。jquery

Spring MVC是基於 Servlet 的一個 MVC 框架 主要解決 WEB 開發的問題,由於 Spring 的配置很是複雜,各類XML、 JavaConfig、hin處理起來比較繁瑣。web

因而爲了簡化開發者的使用,從而創造性地推出了Spring boot,約定優於配置,簡化了spring的配置流程。spring

說得更簡便一些:Spring 最初利用「工廠模式」(DI)和「代理模式」(AOP)解耦應用組件。編程

你們以爲挺好用,因而按照這種模式搞了一個 MVC框架(一些用Spring 解耦的組件),用開發 web 應用( SpringMVC )。json

而後有發現每次開發都寫不少樣板代碼,爲了簡化工做流程,因而開發出了一些「懶人整合包」(starter),這套就是 Spring Boot。api

Spring MVC的功能Spring MVC提供了一種輕度耦合的方式來開發web應用。Spring MVC是Spring的一個模塊,式一個web框架。跨域

經過Dispatcher Servlet, ModelAndView 和 View Resolver,開發web應用變得很容易。解決的問題領域是網站應用程序或者服務開發——URL路由、Session、模板引擎、靜態Web資源等等。

Spring Boot的功能Spring Boot實現了自動配置,下降了項目搭建的複雜度。

衆所周知Spring框架須要進行大量的配置,Spring Boot引入自動配置的概念,讓項目設置變得很容易。

Spring Boot自己並不提供Spring框架的核心特性以及擴展功能,只是用於快速、敏捷地開發新一代基於Spring框架的應用程序。也就是說,它並非用來替代Spring的解決方案,而是和Spring框架緊密結合用於提高Spring開發者體驗的工具。

同時它集成了大量經常使用的第三方庫配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot應用中這些第三方庫幾乎能夠零配置的開箱即用(out-of-the-box),大部分的Spring Boot應用都只須要很是少許的配置代碼,開發者可以更加專一於業務邏輯。Spring Boot只是承載者,輔助你簡化項目搭建過程的。若是承載的是WEB項目,使用Spring MVC做爲MVC框架,那麼工做流程和你上面描述的是徹底同樣的,由於這部分工做是Spring MVC作的而不是Spring Boot。對使用者來講,換用Spring Boot之後,項目初始化方法變了,配置文件變了,另外就是不須要單獨安裝Tomcat這類容器服務器了,maven打出jar包直接跑起來就是個網站,但你最核心的業務邏輯實現與業務流程實現沒有任何變化。

因此,用最簡練的語言歸納就是:

Spring 是一個「引擎」;

Spring MVC 是基於Spring的一個 MVC 框架 ;

Spring Boot 是基於Spring4的條件註冊的一套快速開發整合包。

Spring MVC自動配置

Spring Boot爲Spring MVC提供的auto-configuration適用於大多數應用,並在Spring默認功能上添加了如下特性:

 引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。

 對靜態資源的支持,包括對WebJars的支持。

 自動註冊Converter,GenericConverter,Formatter beans。

 對HttpMessageConverters的支持。

 自動註冊MessageCodeResolver。

 對靜態index.html的支持。

 對自定義Favicon的支持。

 自動使用ConfigurableWebBindingInitializer bean。

若是保留Spring Boot MVC特性,你只需添加其餘的MVC配置(攔截器,格式化處理器,視圖控制器等)。你能夠添加本身的WebMvcConfigurerAdapter類型的@Configuration類,而不須要註解@EnableWebMvc。若是但願使用自定義的RequestMappingHandlerMapping,RequestMappingHandlerAdapter,或ExceptionHandlerExceptionResolver,你能夠聲明一個WebMvcRegistrationsAdapter實例提供這些組件。

若是想全面控制Spring MVC,你能夠添加本身的@Configuration,並使用@EnableWebMvc註解。

HttpMessageConverters

Spring MVC使用HttpMessageConverter接口轉換HTTP請求和響應,合適的默認配置能夠開箱即用,例如對象自動轉換爲JSON(使用Jackson庫)或XML(若是Jackson XML擴展可用,不然使用JAXB),字符串默認使用UTF-8編碼。

可使用Spring Boot的HttpMessageConverters類添加或自定義轉換類:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;  

import org.springframework.context.annotation.*;  

import org.springframework.http.converter.*;  

@Configuration  

public class MyConfiguration {  

    @Bean  

    public HttpMessageConverters customConverters() {  

HttpMessageConverter<?> additional = ...  

HttpMessageConverter<?> another = ...  

        return new HttpMessageConverters(additional, another);  

    }  

上下文中出現的全部HttpMessageConverter bean都將添加到converters列表,你能夠經過這種方式覆蓋默認的轉換器列表(converters)。

自定義JSON序列化器和反序列化器

若是使用Jackson序列化,反序列化JSON數據,你可能想編寫本身的JsonSerializer和JsonDeserializer類。自定義序列化器(serializers)一般經過Module註冊到Jackson,但Spring Boot提供了@JsonComponent註解這一替代方式,它能輕鬆的將序列化器註冊爲Spring Beans。

MessageCodesResolver

Spring MVC有一個實現策略,用於從綁定的errors產生用來渲染錯誤信息的錯誤碼:MessageCodesResolver。Spring Boot會自動爲你建立該實現,只要設置spring.mvc.message-codes-resolver.format屬性爲PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE(具體查看DefaultMessageCodesResolver.Format枚舉值)。

靜態內容

默認狀況下,Spring Boot從classpath下的/static(/public,/resources或/META-INF/resources)文件夾,或從ServletContext根目錄提供靜態內容。這是經過Spring MVC的ResourceHttpRequestHandler實現的,你能夠自定義WebMvcConfigurerAdapter並覆寫addResourceHandlers方法來改變該行爲(加載靜態文件)。

在單機web應用中,容器會啓動默認的servlet,並用它加載ServletContext根目錄下的內容以響應那些Spring不處理的請求。大多數狀況下這都不會發生(除非你修改默認的MVC配置),由於Spring總可以經過DispatcherServlet處理這些請求。

你能夠設置spring.resources.staticLocations屬性自定義靜態資源的位置(配置一系列目錄位置代替默認的值),若是你這樣作,默認的歡迎頁面將從自定義位置加載,因此只要這些路徑中的任何地方有一個index.html,它都會成爲應用的主頁。

此外,除了上述標準的靜態資源位置,有個例外狀況是Webjars內容。任何在/webjars/**路徑下的資源都將從jar文件中提供,只要它們以Webjars的格式打包。

注 若是你的應用將被打包成jar,那就不要使用src/main/webapp文件夾。儘管該文件夾是一般的標準格式,但它僅在打包成war的狀況下起做用,在打包成jar時,多數構建工具都會默認忽略它。

Spring Boot也支持Spring MVC提供的高級資源處理特性,可用於清除緩存的靜態資源或對WebJar使用版本無感知的URLs。

若是想使用針對WebJars版本無感知的URLs(version agnostic),只須要添加webjars-locator依賴,而後聲明你的Webjar。以jQuery爲例,"/webjars/jquery/dist/jquery.min.js"實際爲"/webjars/jquery/x.y.z/dist/jquery.min.js",x.y.z爲Webjar的版本。

注 若是使用JBoss,你須要聲明webjars-locator-jboss-vfs依賴而不是webjars-locator,不然全部的Webjars將解析爲404。

如下的配置爲全部的靜態資源提供一種緩存清除(cache busting)方案,其實是將內容hash添加到URLs中,好比<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>:

spring.resources.chain.strategy.content.enabled=true  

spring.resources.chain.strategy.content.paths=/** 

注 實現該功能的是ResourceUrlEncodingFilter,它在模板運行期會重寫資源連接,Thymeleaf,Velocity和FreeMarker會自動配置該filter,JSP須要手動配置。其餘模板引擎還沒自動支持,不過你可使用ResourceUrlProvider自定義模塊宏或幫助類。

當使用好比JavaScript模塊加載器動態加載資源時,重命名文件是不行的,這也是提供其餘策略並能結合使用的緣由。下面是一個"fixed"策略,在URL中添加一個靜態version字符串而不須要改變文件名:

spring.resources.chain.strategy.content.enabled=true  

spring.resources.chain.strategy.content.paths=/**  

spring.resources.chain.strategy.fixed.enabled=true  

spring.resources.chain.strategy.fixed.paths=/js/lib/  

spring.resources.chain.strategy.fixed.version=v12 

使用以上策略,JavaScript模塊加載器加載"/js/lib/"下的文件時會使用一個固定的版本策略"/v12/js/lib/mymodule.js",其餘資源仍舊使用內容hash的方式<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>。查看ResourceProperties獲取更多支持的選項。

歡迎頁面

Spring Boot支持靜態和模板歡迎頁面。它首先index.html在配置的靜態內容位置中查找 文件。若是找不到,則會查找index模板。若是找到任何一個,它將自動用做應用程序的歡迎頁面。、

自定義Favicon

Spring Boot favicon.ico在配置的靜態內容位置和類路徑的根目錄(按此順序)中查找a 。若是存在這樣的文件,它會自動用做應用程序的圖標。

路徑匹配和內容協商

Spring MVC能夠經過查看請求路徑並將它匹配到應用程序中定義的映射(例如@GetMapping Controller方法上的註釋),將傳入的HTTP請求映射處處理程序。

Spring Boot選擇默認禁用後綴模式匹配,這意味着請求"GET /projects/spring-boot.json"不會匹配 @GetMapping("/projects/spring-boot")映射。這被認爲是Spring MVC應用程序的 最佳實踐。此功能在過去對於沒有發送正確的「Accept」請求標頭的HTTP客戶端來講很是有用; 咱們須要確保將正確的內容類型發送到客戶端。現在,內容協商更可靠。

還有其餘一些方法能夠處理不一致地發送適當的「接受」請求標頭的HTTP客戶端。咱們可使用查詢參數來確保相似的請求"GET /projects/spring-boot?format=json" 將映射到@GetMapping("/projects/spring-boot")如下內容,而不是使用後綴匹配:

spring.mvc.contentnegotiation.favor-parameter = true  

#咱們能夠更改參數名稱,默認爲「格式」:  

#spring.mvc.contentnegotiation.parameter-name = myparam  

#咱們還能夠經過如下方式註冊其餘文件擴展名/媒體類型:  

spring.mvc.contentnegotiation.media-types.markdown = text / markdown 

若是您瞭解注意事項並仍然但願應用程序使用後綴模式匹配,則須要進行如下配置:

spring.mvc.contentnegotiation.favor-path-extension = true  

#您也能夠將該功能限制爲已知擴展  

#spring.mvc.pathmatch.use-registered-suffix-pattern = true  

#咱們還能夠經過如下方式註冊其餘文件擴展名/媒體類型:  

#spring.mvc.contentnegotiation.media-types.adoc = text / asciidoc 

ConfigurableWebBindingInitializer

Spring MVC使用WebBindingInitializer爲每一個特殊的請求初始化相應的WebDataBinder,若是你建立本身的ConfigurableWebBindingInitializer @Bean,Spring Boot會自動配置Spring MVC使用它。

模板引擎

正如REST web服務,你也可使用Spring MVC提供動態HTML內容。Spring MVC支持各類各樣的模板技術,包括Velocity, FreeMarker和JSPs,不少其餘的模板引擎也提供它們本身的Spring MVC集成。

Spring Boot爲如下的模板引擎提供自動配置支持:

 FreeMarker

 Groovy

 Thymeleaf

 Velocity(1.4已再也不支持)

 Mustache

注:因爲在內嵌servlet容器中使用JSPs存在一些已知的限制,因此建議儘可能不使用它們。

使用以上引擎中的任何一種,並採用默認配置,則模塊會從src/main/resources/templates自動加載。

注:IntelliJ IDEA根據你運行應用的方式會對classpath進行不一樣的排序。在IDE裏經過main方法運行應用,跟從Maven,或Gradle,或打包好的jar中運行相比會致使不一樣的順序,這可能致使Spring Boot不能從classpath下成功地找到模板。若是遇到這個問題,你能夠在IDE裏從新對classpath進行排序,將模塊的類和資源放到第一位。或者,你能夠配置模塊的前綴爲classpath*:/templates/,這樣會查找classpath下的全部模板目錄。

錯誤處理

Spring Boot默認提供一個/error映射用來以合適的方式處理全部的錯誤,並將它註冊爲servlet容器中全局的 錯誤頁面。對於機器客戶端(相對於瀏覽器而言,瀏覽器偏重於人的行爲),它會產生一個具備詳細錯誤,HTTP狀態,異常信息的JSON響應。對於瀏覽器客戶端,它會產生一個白色標籤樣式(whitelabel)的錯誤視圖,該視圖將以HTML格式顯示一樣的數據(能夠添加一個解析爲'error'的View來自定義它)。爲了徹底替換默認的行爲,你能夠實現ErrorController,並註冊一個該類型的bean定義,或簡單地添加一個ErrorAttributes類型的bean以使用現存的機制,只是替換顯示的內容。

注BasicErrorController能夠做爲自定義ErrorController的基類,若是你想添加對新context type的處理(默認處理text/html),這會頗有幫助。你只須要繼承BasicErrorController,添加一個public方法,並註解帶有produces屬性的@RequestMapping,而後建立該新類型的bean。

你也能夠定義一個@ControllerAdvice去自定義某個特殊controller或exception類型的JSON文檔:

@ControllerAdvice(basePackageClasses = FooController.class)  

public class FooControllerAdvice extends ResponseEntityExceptionHandler {  

    @ExceptionHandler(YourException.class)  

    @ResponseBody  

ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {  

HttpStatusstatus = getStatus(request);  

return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);  

    }  

    private HttpStatus getStatus(HttpServletRequest request) {  

IntegerstatusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");  

if (statusCode == null) {  

            return HttpStatus.INTERNAL_SERVER_ERROR;  

        }  

        return HttpStatus.valueOf(statusCode);  

    }  

在以上示例中,若是跟FooController相同package的某個controller拋出YourException,一個CustomerErrorType類型的POJO的json展現將代替ErrorAttributes展現。

自定義錯誤頁面

若是想爲某個給定的狀態碼展現一個自定義的HTML錯誤頁面,你須要將文件添加到/error文件夾下。錯誤頁面既能夠是靜態HTML(好比,任何靜態資源文件夾下添加的),也能夠是使用模板構建的,文件名必須是明確的狀態碼或一系列標籤。

例如,映射404到一個靜態HTML文件,你的目錄結構可能以下:

src/  

 +- main/  

     +- java/  

|   +<source code>  

     +- resources/  

         +- public/  

             +- error/  

             |   +- 404.html  

+-<other public assets> 

使用FreeMarker模板映射全部5xx錯誤,你須要以下的目錄結構:

src/  

 +- main/  

     +- java/  

|   +<source code>  

     +- resources/  

         +- templates/  

             +- error/  

             |   +- 5xx.ftl  

+-<other templates> 

對於更復雜的映射,你能夠添加實現ErrorViewResolver接口的beans:

public class MyErrorViewResolver implements ErrorViewResolver {  

    @Override  

    public ModelAndView resolveErrorView(HttpServletRequest request,  

HttpStatus status, Map<String, Object> model) {  

        // Use the request or status to optionally return a ModelAndView  

        return ...  

    }  

你也可使用Spring MVC特性,好比@ExceptionHandler方法和@ControllerAdvice,ErrorController將處理全部未處理的異常。

映射Spring MVC之外的錯誤頁面

對於不使用Spring MVC的應用,你能夠經過ErrorPageRegistrar接口直接註冊ErrorPages。該抽象直接工做於底層內嵌servlet容器,即便你沒有Spring MVC的DispatcherServlet,它們仍舊能夠工做。

@Bean  

public ErrorPageRegistrar errorPageRegistrar(){  

    return new MyErrorPageRegistrar();  

}  

// ...  

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {  

    @Override  

    public void registerErrorPages(ErrorPageRegistry registry) {  

        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));  

    }  

注.若是你註冊一個ErrorPage,該頁面須要被一個Filter處理(在一些非Spring web框架中很常見,好比Jersey,Wicket),那麼該Filter須要明確註冊爲一個ERROR分發器(dispatcher),例如:

@Bean  

public FilterRegistrationBean myFilter() {  

FilterRegistrationBeanregistration = new FilterRegistrationBean();  

    registration.setFilter(new MyFilter());  

    ...  

    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));  

    return registration;  

(默認的FilterRegistrationBean不包含ERROR dispatcher類型)。

WebSphere應用服務器的錯誤處理

當部署到一個servlet容器時,Spring Boot經過它的錯誤頁面過濾器將帶有錯誤狀態的請求轉發到恰當的錯誤頁面。request只有在response還沒提交時才能轉發(forwarded)到正確的錯誤頁面,而WebSphere應用服務器8.0及後續版本默認狀況會在servlet方法成功執行後提交response,你須要設置com.ibm.ws.webcontainer.invokeFlushAfterService屬性爲false來關閉該行爲。

Spring HATEOAS

若是正在開發基於超媒體的RESTful API,你可能須要Spring HATEOAS,而Spring Boot會爲其提供自動配置,這在大多數應用中都運做良好。 自動配置取代了@EnableHypermediaSupport,只需註冊必定數量的beans就能輕鬆構建基於超媒體的應用,這些beans包括LinkDiscoverers(客戶端支持),ObjectMapper(用於將響應編排爲想要的形式)。ObjectMapper能夠根據spring.jackson.*屬性或Jackson2ObjectMapperBuilder bean進行自定義。

經過註解@EnableHypermediaSupport,你能夠控制Spring HATEOAS的配置,但這會禁用上述ObjectMapper的自定義功能。

CORS支持

跨域資源共享(CORS)是一個大多數瀏覽器都實現了的W3C標準,它容許你以靈活的方式指定跨域請求如何被受權,而不是採用那些不安全,性能低的方式,好比IFRAME或JSONP。

從4.2版本開始,Spring MVC對CORS提供開箱即用的支持。不用添加任何特殊配置,只須要在Spring Boot應用的controller方法上註解@CrossOrigin,並添加CORS配置。經過註冊一個自定義addCorsMappings(CorsRegistry)方法的WebMvcConfigurer bean能夠指定全局CORS配置:

@Configuration  

public class MyConfiguration {  

    @Bean  

    public WebMvcConfigurer corsConfigurer() {  

        return new WebMvcConfigurerAdapter() {  

            @Override  

            public void addCorsMappings(CorsRegistry registry) {  

                registry.addMapping("/api/**");  

            }  

        };  

    }  

推薦一個交流學習羣:697-57-9751 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多:

 

相關文章
相關標籤/搜索