30、MVC项目实战(二):完成MVC项目的测试、部署与运维,总结MVC设计模式的核心价值与学习路径
好,终于到了最后一章。说实话,能坚持看到这里,你已经比大多数人都强了。前面我们搭了框架、写了业务、联了数据库,但一个真正的MVC项目,光能跑起来远远不够。
这一章,我们聊聊怎么让项目稳定地跑、放心地部署、长久地维护。顺便,我会把MVC的核心价值和学习路径做个总结——嗯,算是给这30章画个句号。
30.1 单元测试:别让重构变成拆弹
我见过太多团队,一提到重构就头皮发麻。为什么?因为没测试。改一行代码,不知道炸了哪里。
MVC的分层结构,天然适合写单元测试。Model层不依赖UI,Controller层可以mock View,Service层可以mock Repository。每一层都能独立验证。
我个人习惯用 JUnit 5 + Mockito 做Java项目的测试。下面是一个典型的Service层测试示例:
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
public void testCreateUser_ShouldReturnUserDTO() {
// 准备
UserCreateRequest request = new UserCreateRequest();
request.setUsername("test_user");
request.setEmail("test@example.com");
User savedUser = new User(1L, "test_user", "test@example.com");
when(userRepository.save(any(User.class))).thenReturn(savedUser);
// 执行
UserDTO result = userService.createUser(request);
// 验证
assertNotNull(result);
assertEquals("test_user", result.getUsername());
verify(userRepository, times(1)).save(any(User.class));
}
}
30.2 集成测试:让三层真正协作起来
单元测试只能保证单个类没问题。但MVC的三层协作,需要集成测试来验证。
我建议用 Spring Boot Test 或者 Testcontainers 来启动真实环境。下面是一个Controller层的集成测试:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testCreateUser_ShouldReturn201() throws Exception {
String requestBody = """
{
"username": "test_user",
"email": "test@example.com"
}
""";
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.username").value("test_user"));
}
}
30.3 部署:从开发机到生产环境
部署这件事,说白了就是把代码从你的电脑搬到服务器上。但中间的门道,比你想象的多。
我推荐用 Docker + CI/CD 的方式。下面是一个简单的Dockerfile:
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
配合 docker-compose.yml 把MySQL、Redis、Nginx一起编排起来:
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mvc_demo
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mvc_demo
30.4 运维:线上问题排查三板斧
项目上线后,运维才是真正的考验。我总结了三板斧:
- 日志:统一用SLF4J + Logback,按天滚动,保留30天。关键业务打INFO,异常打ERROR,别打太多DEBUG。
- 监控:用Prometheus + Grafana,监控接口QPS、响应时间、错误率。我习惯给每个接口加一个
@Timed注解。 - 告警:错误率超过1%就发钉钉/企业微信通知。别等用户反馈才知道系统挂了。
下面是一个简单的健康检查接口:
@RestController
@RequestMapping("/actuator")
public class HealthController {
@GetMapping("/health")
public ResponseEntity<String> health() {
// 检查数据库连接、缓存连接等
return ResponseEntity.ok("UP");
}
}
30.5 MVC核心价值:为什么它值得学?
学完这30章,你可能会问:MVC到底好在哪?我总结三点:
| 维度 | MVC的优势 | 没有MVC会怎样 |
|---|---|---|
| 可维护性 | 修改UI不影响业务逻辑 | 改个按钮颜色,数据库查询崩了 |
| 可测试性 | 每层可以独立测试 | 测试必须启动整个应用 |
| 团队协作 | 前端、后端、数据层可以并行开发 | 所有人改同一个文件,天天冲突 |
说白了,MVC不是银弹,但它提供了一个经过验证的分层范式。你想想看,为什么Spring MVC、ASP.NET MVC、Django这些框架都长一个样?因为大家都踩过同样的坑,最后发现还是分层最靠谱。
30.6 学习路径:从入门到精通
最后,我整理了一条学习路径,供你参考:
- 第一阶段(1-2周):理解MVC概念,手写一个最简单的MVC Demo(不用框架)。
- 第二阶段(2-4周):学习Spring MVC或类似框架,掌握路由、参数绑定、拦截器。
- 第三阶段(4-8周):结合MyBatis/JPA做完整CRUD,理解Service层和Repository层的职责。
- 第四阶段(8-12周):做一个小型项目(比如博客系统),加入权限、缓存、日志。
- 第五阶段(持续):阅读优秀开源项目的源码,比如RuoYi、JFinal,学习别人的分层技巧。
30.7 本章知识体系图
下面这张图,帮你回顾本章的核心内容:
30.8 写在最后
30章,从入门到实战,我们走完了MVC的完整旅程。说实话,MVC不是什么高深的技术,但它是一个合格工程师的必修课。
我见过很多新人,上来就学微服务、学DDD,结果连三层架构都写不清楚。其实你想想看,MVC都搞不定,怎么去理解更复杂的东西?
最后送你一句话:设计模式不是用来炫技的,是用来解决问题的。MVC帮你解决了代码组织的问题,剩下的,就看你怎么用了。
加油,未来的架构师。
公众号:蓝海资料掘金营,微信deep3321