Spring Boot Web 开发

SB-Web-Starter 默认行为分析

依赖的 starter:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

最终会引入:

1
2
3
4
5
6
7
8
9
10
11
12
13
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>xxx</version>
<scope>compile</scope>
</dependency>

主程序启动
@SpringBootApplication
@EnableAutoConfiguration
@Import({AutoConfigurationImportSelector.class})
ImportCandidates.load(this.autoConfigurationAnnotation, this.getBeanClassLoader())
spring-boot-autoconfigure/META-INF/spring/xxx/AutoConfiguration.imports


有哪些配置和组件

最终导入如下 100 多个 XxxAutoConfiguration:

1
2
3
4
5
6
7
8
9
10
11
...
org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration
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.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
...


有哪些可选配置

查找可以得到,当定了如下一些配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ConfigurationProperties("server")
public class ServerProperties {...}

@ConditionalOnBooleanProperty("server.servlet.encoding.enabled")
public class HttpEncodingAutoConfiguration {...}

@ConfigurationProperties("spring.web")
public class WebProperties {...}

@ConfigurationProperties("spring.mvc")
public class WebMvcProperties {...}

@ConfigurationProperties("spring.servlet.multipart")
public class MultipartProperties {...}

对应的配置文件:

1
2
3
4
5
6
7
8
9
server:
xxx # Tomcat等服务器以及编码相关的配置
spring:
web:
xxx # SpringWeb场景通用配置
mvc:
xxx # SpringMVC所有的配置
servlet:
xxx # 文件上传相关


默认的一些效果

spring-boot-starter-web 默认的配置:

  • 包含了 ContentNegotiatingViewResolver、BeanNameViewResolver 组件,方便视图解析
  • 默认的静态资源处理机制:静态资源放在 static 文件夹下即可直接访问
  • 自动注册了 Conveter、GenericConverter、Formatter 组件,适配常见数据转换和格式化需求
  • 支持 HttpMessageConverters,可以方便返回 json 等数据类型
  • 注册 MessageCodesResolver,方便国际化及错误消息处理
  • 支持静态 index.html
  • 自动使用 ConfigurableWebBindingInitializer,实现消息处理、数据绑定、类型转化等功能。


三种开发模式

全自动模式:开箱即用。核心特征是没有任何 WebMvcConfigurer 或相关的配置类。Spring Boot 依靠 WebMvcAutoConfiguration 类,按照它认为最通用的方式帮你装配好了所有零件。下面这个示例你可以通过 localhost:8080/api/greet 访问,也可以通过 localhost:8080/index.html 访问 static 目录下的静态文件。

1
2
3
4
5
6
7
8
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/greet")
public String greet() {
return "Hello from Owlias!"; // 自动转为 JSON 或字符串
}
}

手自一体:这是生产环境中最推荐、核心是编写 @Configuration 类并实现 WebMvcConfigurer,但千万不要加 @EnableWebMvc

  • Spring Boot 依然会自动配置静态资源处理(如 /static)、默认的消息转换器(JSON 处理)等。你可以通过重写方法,追加自己的拦截器(Interceptors)、格式化器(Formatters)或跨域规则(CORS)。
  • 如果你想改动更底层的东西,比如自定义 RequestMappingHandlerMapping(例如为了实现“接口版本控制”),就实现这个接口。它依然会和 Spring Boot 的默认机制和谐共存。

下面手自一体模式,添加了一个拦截器(比如校验 IM 消息的 Token),但又不想破坏 Spring Boot 原有的静态资源处理能力。结果是拦截器生效了,同时你的静态资源映射(如 /js/)和默认的 JSON 解析器依然正常工作。这就是 “既要也要”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
// 注意:这里绝对不能加 @EnableWebMvc
public class MyWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
// 添加一个自定义拦截器,只拦截 /api 下的请求
registry.addInterceptor(new MyAuthInterceptor())
.addPathPatterns("/api/**");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 快捷映射:把 /login 路径直接指向 login.html 页面,不需要写 Controller
registry.addViewController("/login").setViewName("login");
}
}

全手动:核心是在配置类上标注 @EnableWebMvc。一旦你加上这个注解,Spring Boot 的 WebMvcAutoConfiguration 就会看到已经存在了 DelegatingWebMvcConfiguration,然后触发 @ConditionalOnMissingBean 机制,自动配置全面撤退。下面全手动模式下,你必须手动配置每一个细节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
@EnableWebMvc // 开启此注解,Spring Boot 自动配置彻底“撤退”
public class CompleteCustomConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyAuthInterceptor()).addPathPatterns("/**");
}

// 重点:你必须手动配置静态资源处理器,否则所有静态文件(CSS/JS)都会报 404
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}

// 你甚至需要手动配置 HttpMessageConverter,否则可能连 JSON 都返回不了
}

在 Spring Boot 中,Web 功能是由一个叫 WebMvcAutoConfiguration 的类自动打理的。但这个类有一个前提条件(通过注解标注):@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)。当你标注了 @EnableWebMvc,它导入的 DelegatingWebMvcConfiguration 正是 WebMvcConfigurationSupport 的子类,既然你自己手动开启了 MVC 核心配置,那sb就不插手了。那么消失的默认值都有哪些呢?

  • 静态资源路径:不再支持 /static, /public, /resources 自动映射。访问图片、JS 会直接 404。
  • 默认 JSON 转换器:比如对 Jackson 的一些默认定制(如日期格式化)可能会失效。
  • 欢迎页 (Index.html):自动映射 index.html 到根路径的功能失效。
  • 错误页面处理:默认的 /error 映射和 WhiteLabel Error Page 消失。
  • Favicon:网站图标自动加载失效。