深入解析 Spring MVC:架构、组件与最佳实践

文章目录

1. DispatcherServlet

DispatcherServlet 是 Spring MVC 的前端控制器,它负责接收所有的 HTTP 请求,并将请求分发到相应的处理器。它是整个 Spring MVC 框架的核心组件。

  • 初始化DispatcherServlet 在启动时会初始化一系列的组件,如 HandlerMappingHandlerAdapterViewResolver 等。
  • 请求处理 :接收到请求后,DispatcherServlet 会通过 HandlerMapping 找到合适的处理器,然后通过 HandlerAdapter 调用处理器方法。
2. HandlerMapping

HandlerMapping 负责将请求映射到处理器。Spring MVC 提供了多种 HandlerMapping 实现,包括:

  • RequestMappingHandlerMapping :基于 @RequestMapping 注解进行请求映射。
  • BeanNameUrlHandlerMapping:基于 Bean 名称进行请求映射。
  • SimpleUrlHandlerMapping:基于 URL 模式进行请求映射。
3. HandlerAdapter

HandlerAdapter 负责调用处理器方法。Spring MVC 提供了多种 HandlerAdapter 实现,包括:

  • RequestMappingHandlerAdapter :支持基于 @RequestMapping 注解的方法调用。
  • HttpRequestHandlerAdapter :支持 HttpRequestHandler 接口的方法调用。
4. Controller

控制器是处理请求的主要组件。在 Spring MVC 中,控制器类通常使用 @Controller 注解标记,并且方法上使用 @RequestMapping 或其派生注解(如 @GetMapping, @PostMapping)来指定处理哪些请求。

5. ModelAndView

ModelAndView 对象用于封装模型数据和视图信息。控制器方法可以返回 ModelAndView 对象,其中包含模型数据和视图名称。

6. ViewResolver

视图解析器负责将逻辑视图名称解析为具体的视图对象。常用的视图解析器有:

  • InternalResourceViewResolver:用于 JSP 视图。
  • ThymeleafViewResolver:用于 Thymeleaf 视图。
  • FreeMarkerViewResolver:用于 FreeMarker 视图。
7. View

视图负责渲染最终的页面,展示给用户。视图可以是 JSP、FreeMarker、Thymeleaf 等模板引擎生成的页面。

工作流程

  1. 客户端发送请求:客户端(如浏览器)发送 HTTP 请求到服务器。
  2. 请求到达 DispatcherServlet :请求被 DispatcherServlet 捕获。
  3. HandlerMapping 定位处理器DispatcherServlet 使用 HandlerMapping 查找处理请求的控制器方法。
  4. HandlerAdapter 调用处理器DispatcherServlet 使用 HandlerAdapter 调用控制器方法。
  5. 控制器处理请求 :控制器方法处理请求,返回 ModelAndView 对象。
  6. ViewResolver 解析视图DispatcherServlet 使用 ViewResolver 将逻辑视图名称解析为具体的视图对象。
  7. 视图渲染:视图对象渲染最终的页面,并返回给客户端。

配置方式

XML 配置

传统的 Spring MVC 配置通常是通过 XML 文件完成的。以下是一个简单的 XML 配置示例:

xml 复制代码
<!-- web.xml -->
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- dispatcher-servlet.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描 Controller -->
    <context:component-scan base-package="com.example.controller" />

    <!-- 启用 MVC 注解驱动 -->
    <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 配置

现代的 Spring MVC 项目通常使用 Java 配置。以下是一个简单的 Java 配置示例:

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan(basePackages = "com.example.controller")
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

最佳实践

  1. 分层设计:将应用分为控制器层、服务层和数据访问层,保持各层职责清晰。
  2. 异常处理 :使用 @ControllerAdvice@ExceptionHandler 注解来集中处理异常。
  3. 数据验证:使用 JSR-303 标准的数据验证框架(如 Hibernate Validator)来验证请求参数。
  4. 国际化:使用 Spring 的国际化支持来提供多语言界面。
  5. 安全性:使用 Spring Security 来保护应用的安全性。
  6. 性能优化:合理使用缓存、异步处理等技术来提升应用性能。

示例项目

假设我们有一个简单的 Spring Boot 项目,使用 Spring MVC 构建一个基本的 Web 应用程序。

项目目录结构
src/main/java
│── com.example
│   └── controller
│       └── HelloWorldController.java
│── com.example.service
│   └── HelloWorldService.java
│── com.example.repository
│   └── HelloWorldRepository.java
└── Application.java

src/main/resources
│── static
│── templates
│── application.properties
控制器 (HelloWorldController.java)
java 复制代码
package com.example.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.service.HelloWorldService;

@Controller
public class HelloWorldController {

    @Autowired
    private HelloWorldService helloWorldService;

    @GetMapping("/hello")
    public String hello(Model model) {
        String message = helloWorldService.getMessage();
        model.addAttribute("message", message);
        return "hello"; // 返回视图名称
    }
}
服务层 (HelloWorldService.java)
java 复制代码
package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class HelloWorldService {

    public String getMessage() {
        return "Hello, Spring MVC!";
    }
}
视图 (hello.jsp)
jsp 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
配置文件 (application.properties)
properties 复制代码
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
全局异常处理 (GlobalExceptionHandler.java)
java 复制代码
package com.example.controller;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleException(Exception ex) {
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("errorMessage", ex.getMessage());
        return modelAndView;
    }
}
相关推荐
Allen_LVyingbo1 小时前
低代码与微服务融合在医疗集团中的补充应用探究
职场和发展·架构·健康医疗
悠悠龙龙2 小时前
框架模块说明 #05 权限管理_03
java·开发语言·spring
运维&陈同学5 小时前
【Dubbo03】消息队列与微服务之dubbo-admin 二进制与编译安装
linux·运维·服务器·后端·微服务·云原生·架构·dubbo
fa_lsyk6 小时前
SpringMVC:SpringMVC的bean加载机制
java·spring·servlet·mvc
K丶one6 小时前
Spring boot + Vue2 整合人脸识别登录
java·spring boot·spring
沈询-阿里7 小时前
java调用ai模型:使用国产通义千问完成基于知识库的问答
java·人工智能·spring
2401_857622668 小时前
SpringBoot 架构助力夕阳红公寓管理系统可持续发展战略
spring boot·后端·架构
liuxin334455668 小时前
以 SpringBoot 为基石,MVC 为架构的高校办公室行政事务管理系统设计与实现
spring boot·架构·mvc
武昌库里写JAVA9 小时前
框架5:SpringBoot 2 - 核心功能
spring boot·spring·毕业设计·layui·课程设计
zzb15809 小时前
部门管理系统Spring 登录校验模块开发学习
java·后端·学习·spring