spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,固然就包含spring mvc。spring mvc 是只是spring 处理web层请求的一个模块。所以他们的关系大概就是这样:spring mvc < spring <springboot。css
Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面的编程,而后在此二者的基础上实现了其余延伸产品的高级功能。html
Spring MVC是基于 Servlet 的一个 MVC 框架 主要解决 WEB 开发的问题,由于 Spring 的配置很是复杂,各类XML、 JavaConfig、hin处理起来比较繁琐。java
因而为了简化开发者的使用,从而创造性地推出了Spring boot,约定优于配置,简化了spring的配置流程。jquery
说得更简便一些:Spring 最初利用“工厂模式”(DI)和“代理模式”(AOP)解耦应用组件。git
你们以为挺好用,因而按照这种模式搞了一个 MVC框架(一些用Spring 解耦的组件),用开发 web 应用( SpringMVC )。github
而后有发现每次开发都写不少样板代码,为了简化工做流程,因而开发出了一些“懒人整合包”(starter),这套就是 Spring Boot。web
Spring MVC的功能Spring MVC提供了一种轻度耦合的方式来开发web应用。Spring MVC是Spring的一个模块,式一个web框架。spring
经过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。apache
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 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注解。
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)。
若是使用Jackson序列化,反序列化JSON数据,你可能想编写本身的JsonSerializer和JsonDeserializer类。自定义序列化器(serializers)一般经过Module注册到Jackson,但Spring Boot提供了@JsonComponent注解这一替代方式,它能轻松的将序列化器注册为Spring Beans。
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模板。若是找到任何一个,它将自动用做应用程序的欢迎页面。、
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
Spring MVC使用WebBindingInitializer为每一个特殊的请求初始化相应的WebDataBinder,若是你建立本身的ConfigurableWebBindingInitializer @Bean,Spring Boot会自动配置Spring MVC使用它。
正如REST web服务,你也可使用Spring MVC提供动态HTML内容。Spring MVC支持各类各样的模板技术,包括Velocity, FreeMarker和JSPs,不少其余的模板引擎也提供它们本身的Spring MVC集成。
Spring Boot为如下的模板引擎提供自动配置支持:
Velocity(1.4已再也不支持)
注:因为在内嵌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) { HttpStatus status = getStatus(request); return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status); } private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (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() { FilterRegistrationBean registration = 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来关闭该行为。
若是正在开发基于超媒体的RESTful API,你可能须要Spring HATEOAS,而Spring Boot会为其提供自动配置,这在大多数应用中都运做良好。 自动配置取代了@EnableHypermediaSupport,只需注册必定数量的beans就能轻松构建基于超媒体的应用,这些beans包括LinkDiscoverers(客户端支持),ObjectMapper(用于将响应编排为想要的形式)。ObjectMapper能够根据spring.jackson.*属性或Jackson2ObjectMapperBuilder bean进行自定义。
经过注解@EnableHypermediaSupport,你能够控制Spring HATEOAS的配置,但这会禁用上述ObjectMapper的自定义功能。
跨域资源共享(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/**"); } }; } }
本文相关视频链接