Spring+SpringMVC+MyBatis深入学习及搭建(十一)——SpringMVC架构
在Java企业级应用开发领域,SpringMVC作为Spring框架的核心模块,提供了强大而灵活的Web层解决方案。本文将深入剖析SpringMVC的架构设计、核心组件及请求处理流程,结合最佳实践和代码示例,帮助您全面掌握其内部工作机制。
目录#
- SpringMVC概述
- 核心组件详解
- DispatcherServlet
- HandlerMapping
- HandlerAdapter
- ViewResolver
- 请求处理全流程
- 配置方式对比
- XML配置
- Java Config配置
- 核心实践与最佳实践
- RESTful支持
- 全局异常处理
- 拦截器应用
- 参数验证
- 性能优化建议
- 完整示例代码
- 总结
- 参考文献
1. SpringMVC概述#
SpringMVC是基于前端控制器模式设计的Web框架,其核心设计理念围绕DispatcherServlet展开。采用松耦合的设计架构,通过可插拔组件实现高度可扩展性,完美支持RESTful风格开发。
核心优势:
- 清晰的职责分离
- 灵活的配置选项
- 强大的注解支持
- 无缝集成Spring生态系统
2. 核心组件详解#
2.1 DispatcherServlet(前端控制器)#
作为统一入口点,承担请求分发和响应合成的核心职责。在web.xml中的配置示例:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>2.2 HandlerMapping#
实现请求URL到Controller的映射策略:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 直接映射视图
registry.addViewController("/home").setViewName("home");
}
}2.3 HandlerAdapter#
适配执行处理器方法,支持多种控制器类型:
@Controller注解类- 传统
Controller接口实现 - HttpRequestHandler等
2.4 ViewResolver#
视图解析策略,支持多种视图技术:
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}3. 请求处理全流程#
sequenceDiagram
participant Client
participant DispatcherServlet
participant HandlerMapping
participant HandlerAdapter
participant Controller
participant ViewResolver
Client->>DispatcherServlet: HTTP Request
DispatcherServlet->>HandlerMapping: 查询Handler
HandlerMapping-->>DispatcherServlet: 返回Handler
DispatcherServlet->>HandlerAdapter: 调用Handler
HandlerAdapter->>Controller: 执行对应方法
Controller-->>HandlerAdapter: 返回ModelAndView
HandlerAdapter-->>DispatcherServlet: 返回结果
DispatcherServlet->>ViewResolver: 解析视图
ViewResolver-->>DispatcherServlet: 返回View对象
DispatcherServlet->>View: 渲染视图
View-->>DispatcherServlet: 返回渲染结果
DispatcherServlet->>Client: HTTP Response4. 配置方式对比#
XML配置#
<!-- spring-mvc.xml -->
<beans>
<context:component-scan base-package="com.example.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>Java Config配置(推荐)#
@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}5. 核心实践与最佳实践#
5.1 RESTful支持#
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
// ...
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<Void> createUser(@Valid @RequestBody User user) {
// ...
return ResponseEntity.created(URI.create("/users/" + id)).build();
}
}5.2 全局异常处理#
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(
UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
"USER_NOT_FOUND",
ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
}5.3 拦截器应用#
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
logger.info("Request URL: {}", request.getRequestURL());
return true;
}
}
// 配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor());
}5.4 参数验证#
@PostMapping("/register")
public ResponseEntity<?> registerUser(
@Valid @RequestBody UserRegistrationDto dto,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errors = bindingResult.getFieldErrors()
.stream()
.collect(Collectors.toMap(
FieldError::getField,
FieldError::getDefaultMessage));
return ResponseEntity.badRequest().body(errors);
}
// 处理业务
}6. 性能优化建议#
- 合理使用拦截器:避免在拦截器中执行耗时操作
- 视图解析优化:
- 开启模板缓存(Thymeleaf/FreeMarker)
- 避免不必要的视图跳转
- 合理设置文件上传限制:
@Bean public MultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(5242880); // 5MB return resolver; } - 使用异步处理:
@GetMapping("/async") @ResponseBody public Callable<String> asyncProcessing() { return () -> { Thread.sleep(3000); return "Async result"; }; }
7. 完整示例代码#
@Controller
@RequestMapping("/products")
public class ProductController {
@GetMapping
public String listProducts(Model model) {
model.addAttribute("products", productService.getAllProducts());
return "product/list";
}
@PostMapping("/{id}/purchase")
@ResponseBody
public ResponseEntity<Map<String, Object>> purchaseProduct(
@PathVariable Long id,
@RequestParam int quantity) {
if (quantity <= 0) {
throw new InvalidQuantityException();
}
productService.purchase(id, quantity);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "Purchase successful");
return ResponseEntity.ok(response);
}
}8. 总结#
通过对SpringMVC架构的深度剖析,我们应该掌握:
- ✅ 核心组件:理解DispatcherServlet、HandlerMapping等核心组件的职责
- ✅ 请求流程:熟悉从请求到响应的完整生命周期
- ✅ 现代配置:掌握基于Java Config的现代配置方式
- ✅ 最佳实践:运用RESTful设计、全局异常处理等关键技能
- ✅ 性能优化:了解常见的性能优化点及解决方案
SpringMVC通过其优雅的设计和丰富的功能,为构建企业级Web应用提供了强大基础。
参考文献#
- Spring Framework 官方文档 - Web MVC
- 《Spring in Action》第五版 - Craig Walls
- Spring MVC @RequestMapping注解指南
- Spring Boot参考指南
作者:技术团队
最后更新日期:2023年11月