什么是MVC
MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分
- Model,模型层,指工程中的JavaBean,作用是处理数据JavaBean分为两类:
- 一类称为实体类Bean:专门存储业务数据的,如Studentl、User 等
- 一类称为业务处理Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问。
- View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据
- Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器

MVC的工作流程:
用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器
什么是Spring MVC
三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet
- SpringMVC是Spring的一个后续产品,是Spring的一个子项目
- SpringMVC是Spring为表述层开发提供的一整套完备的解决方案。在表述层框架历经Strust、WebWork,Strust2等诸多产品的历代更迭之后,目前业界普遍选择了SpringMVC作为JavaEE项目表述层开发的首选方案。
spring框架

SpringMVC 特点
- 天生与 Spring 框架集成,如:(IOC,AOP)
- 支持 Restful 风格
- 进行更简洁的 Web 层开发,比servlet更简洁
- 支持灵活的 URL 到页面控制器的映射
- 基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- SpringMVC是一种基于Java实现MVC模型的轻量级web框架优点
使用简单,开发便捷(相比于Servlet)灵活性强
编写第一个程序(使用完全注解的方式)
1.新建一个maven项目,导入组件

2.pom.xml文件导入jar包依赖
| <dependencies> |
| |
| <dependency> |
| <groupId>javax.servlet</groupId> |
| <artifactId>javax.servlet-api</artifactId> |
| <version>3.1.0</version> |
| <scope>provided</scope> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework</groupId> |
| <artifactId>spring-webmvc</artifactId> |
| <version>5.2.10.RELEASE</version> |
| </dependency> |
| </dependencies> |
3. 创建SpringMVC控制器类(等同于Servlet功能)
| @Controller |
| |
| public class HelloController { |
| |
| @RequestMapping("/save") |
| |
| @ResponseBody |
| public String save(){ |
| return "{'module':'springmvc'}"; |
| } |
| } |
4. 创建springMVC配置类,也可以选择使用xml方式
| @Configuration |
| @ComponentScan("controller") |
| public class SpringMVCConfig{ |
| |
| } |
5. 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
| |
| public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { |
| |
| @Override |
| protected WebApplicationContext createServletApplicationContext() { |
| AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); |
| context.register(SpringMVCConfig.class); |
| |
| return context; |
| } |
| |
| @Override |
| protected String[] getServletMappings() { |
| return new String[]{"/"}; |
| } |
| |
| @Override |
| protected WebApplicationContext createRootApplicationContext() { |
| return null; |
| } |
| } |
| |
6.在pom文件添加tomcat插件
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.apache.tomcat.maven</groupId> |
| <artifactId>tomcat7-maven-plugin</artifactId> |
| <version>2.1</version> |
| <configuration> |
| <port>80</port> |
| <path>/</path> |
| </configuration> |
| </plugin> |
| </plugins> |
| </build> |
启动服务器初始化过程
- 服务器启动,执行servletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建WebApplicationContext对象
- 加载SpringMVCConfig
- 执行@ComponentScan加载对应的bean
- 加载Controller,每个@RequestMapping的名称对应一个具体方法
- 执行getServletMappings方法,定义所有的请求都通过SpringMVC
单次请求过程
- 发送请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
- 解析请求路径/save
- 由/save匹配执行对应的方法save()
- 执行save()
- 检测到有@ResponseBody直接将save()方法返回值作为响应体返回给请求方
Controller加载控制与业务bean加载控制
- springMVC相关bean(表现层bean)
- Spring控制的bean
- 业务bean(Service)
- 功能bean(DataSource等)
如何保证在扫描过程中两者不会混杂在一起?
- 分类扫描范围较为精细,准确分类(主要使用方式)
| @Configuration |
| @ComponentScan({"com.Service","com.dao"}) |
| public class SpringConfig(){} |
- 扫描范围较大的包,将其中一些不需要扫描的包排除出去
| @Configuration |
| |
| @ComponentScan(value="com", |
| @ComponentScan(value = "com",excludeFilters = @ComponentScan.Filter( |
| type = FilterType.ANNOTATION, |
| classes = Controller.class |
| )) |
| public class SpringConfig(){} |
| |
同时加载Spring容器和SpringMVC容器
| |
| |
| public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { |
| |
| @Override |
| protected WebApplicationContext createServletApplicationContext() { |
| AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); |
| context.register(SpringMVCConfig.class); |
| return context; |
| } |
| |
| @Override |
| protected String[] getServletMappings() { |
| return new String[]{"/"}; |
| } |
| |
| @Override |
| protected WebApplicationContext createRootApplicationContext() { |
| AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); |
| context.register(SpringConfig.class); |
| return context; |
| } |
| } |
| |
| public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { |
| @Override |
| protected Class<?>[] getRootConfigClasses() { |
| return new Class[]{SpringConfig.class}; |
| } |
| |
| @Override |
| protected Class<?>[] getServletConfigClasses() { |
| return new Class[]{{SpringMVCConfig.class}}; |
| } |
| |
| @Override |
| protected String[] getServletMappings() { |
| return new String[]{"/"}; |
| } |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构