全栈开发学习笔记合集:Java、Spring全家桶、Vue、数据库与中间件技术
简介:本学习笔记合集涵盖全栈开发关键技术,包括Java编程语言、Spring框架体系、MyBatis持久层、Vue前端开发、MySQL与MongoDB数据库、Redis缓存、Docker容器化部署及Nginx服务器配置等内容。适合初学者系统学习或开发者日常查阅使用,帮助掌握现代Web应用开发所需的完整技术栈,提升实战能力与项目部署效率。 
1. Java编程语言核心特性
1.1 Java语言概述与核心优势
Java 是一种面向对象、跨平台、具备自动内存管理机制的高级编程语言,由 Sun Microsystems(现为 Oracle)于 1995 年正式发布。其“一次编写,到处运行”的理念,得益于 Java 虚拟机(JVM)的存在,使得编写的 .java 源代码被编译为 .class 字节码后,可以在任何支持 JVM 的设备上运行。
Java 的核心优势体现在以下方面:
| 特性 | 说明 |
|---|---|
| 面向对象 | 支持封装、继承、多态等 OOP 特性,提升代码复用与模块化设计能力 |
| 平台无关性 | 通过 JVM 实现跨平台运行,极大提升了开发效率和部署灵活性 |
| 自动垃圾回收 | JVM 自动管理内存,降低内存泄漏风险 |
| 强类型与安全性 | 编译时类型检查,运行时安全管理机制,保障系统稳定性 |
| 丰富的类库支持 | 提供大量标准类库(如 java.util 、 java.io 、 java.net 等) |
例如,一个简单的 Java 程序如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, Java World!"); // 输出欢迎信息
}
}
代码说明:
public class HelloWorld:定义一个公共类,类名为HelloWorld,文件名必须与此一致。public static void main(String[] args):Java 应用程序的入口方法,JVM 会从这里开始执行。System.out.println(...):调用标准输出流打印信息到控制台。
通过 JDK 提供的 javac 和 java 命令,我们可以编译并运行该程序:
javac HelloWorld.java # 编译生成 HelloWorld.class
java HelloWorld # 运行程序
Java 的语法结构清晰、逻辑严谨,是构建大型企业级系统(如 Spring 应用)的坚实基础。在后续章节中,我们将逐步深入 Java 的数据类型、流程控制、异常处理、多线程等核心机制,为掌握现代 Java 开发打下坚实基础。
2. Spring框架依赖注入与AOP实现
Spring框架作为Java企业级开发的基石,其核心功能依赖注入(DI)与面向切面编程(AOP)为构建松耦合、可扩展、高可维护性的系统提供了强有力的支持。本章将深入剖析Spring的IoC容器机制、DI的多种实现方式以及AOP在日志记录、权限控制和事务管理中的实际应用,帮助开发者掌握Spring框架的核心编程思想与实践技巧。
2.1 Spring框架概述与IoC容器
2.1.1 Spring框架的模块组成
Spring框架是一个模块化的体系结构,其核心模块可以独立使用,也可以与其他模块组合使用,以满足不同层次的应用需求。Spring框架主要由以下几大模块构成:
| 模块名称 | 主要功能描述 |
|---|---|
| spring-core | 提供Spring框架的基础工具类,如资源加载、类型转换等 |
| spring-beans | 包含BeanFactory,是IoC容器的基础模块 |
| spring-context | 构建在Core和Beans模块之上,提供对Spring上下文的支持 |
| spring-expression | 提供强大的表达式语言支持,用于查询和操作运行时对象 |
| spring-aop | 实现面向切面编程的核心模块 |
| spring-jdbc | 简化JDBC操作,提供异常抽象层 |
| spring-tx | 支持声明式事务管理 |
| spring-web | 提供Web层的基础支持,如集成Servlet、JSP等 |
| spring-webmvc | 实现MVC架构,支持构建Web应用 |
| spring-orm | 提供对Hibernate、JPA等ORM框架的集成支持 |
Spring的模块化设计允许开发者按需引入所需模块,避免不必要的依赖,提升系统的可维护性与可测试性。
2.1.2 IoC容器的基本原理
IoC(Inversion of Control,控制反转)是Spring框架的核心思想。传统的程序控制流程是由程序员通过new关键字主动创建对象,而在IoC模式中,对象的创建、生命周期管理以及依赖关系的维护都交由容器来完成。
Spring IoC容器主要有两种实现方式:
- BeanFactory :是Spring最基础的IoC容器,提供基本的依赖注入功能,延迟加载(Lazy Loading)是其特点。
- ApplicationContext :继承自BeanFactory,提供更多企业级功能,如国际化支持、资源加载、事件传播等,通常在Web项目中使用。
示例代码:使用ApplicationContext创建Bean
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
// 从classpath加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取Bean实例
UserService userService = (UserService) context.getBean("userService");
// 调用方法
userService.createUser();
}
}
配置文件applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 定义UserService Bean -->
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<!-- 注入依赖 -->
<property name="userRepository" ref="userRepository"/>
</bean>
<!-- 定义UserRepository Bean -->
<bean id="userRepository" class="com.example.repository.UserRepositoryImpl"/>
</beans>
代码逻辑分析:
ApplicationContext从指定路径加载XML配置文件。- Spring容器根据配置文件创建
UserService和UserRepository两个Bean。 UserServiceBean通过property标签注入了UserRepositoryBean。- 最终通过
getBean方法获取并调用UserService的方法。
这种将对象的创建和管理交给容器的方式,使得组件之间的耦合度大大降低,提升了系统的可测试性和可维护性。
2.1.3 Bean的生命周期与作用域
Spring中的Bean具有不同的生命周期阶段和作用域,理解这些概念对于开发高质量的Spring应用至关重要。
Bean的生命周期阶段:
- 实例化 :Spring容器通过反射创建Bean实例。
- 属性注入 :容器将配置中定义的属性值或依赖对象注入到Bean中。
- 初始化方法调用 :如果Bean实现了
InitializingBean接口或配置了init-method,则调用初始化方法。 - 使用阶段 :Bean可以被应用程序使用。
- 销毁方法调用 :当容器关闭时,如果Bean实现了
DisposableBean接口或配置了destroy-method,则调用销毁方法。
Bean的作用域(Scope):
| 作用域 | 描述 |
|---|---|
| singleton | 默认作用域,每个Spring IoC容器中仅存在一个Bean实例 |
| prototype | 每次请求都会创建一个新的Bean实例 |
| request | 每个HTTP请求创建一个Bean实例,仅适用于Web应用 |
| session | 每个HTTP会话创建一个Bean实例 |
| application | 与ServletContext生命周期一致的Bean |
| websocket | 每个WebSocket会话创建一个Bean实例 |
示例:定义Bean的作用域与生命周期回调
<bean id="myBean" class="com.example.bean.MyBean"
scope="prototype"
init-method="init"
destroy-method="destroy"/>
public class MyBean {
public void init() {
System.out.println("MyBean is initialized.");
}
public void destroy() {
System.out.println("MyBean is destroyed.");
}
}
说明:
scope="prototype"表示每次获取Bean时都会创建新的实例。init-method和destroy-method分别指定Bean的初始化和销毁方法。- 对于
singleton作用域的Bean,destroy-method在容器关闭时被调用;而prototype作用域的Bean则不会自动调用销毁方法,需开发者手动管理。
2.2 依赖注入(DI)实践
2.2.1 构造方法注入与Setter注入
依赖注入是IoC容器实现松耦合的核心机制。Spring支持多种注入方式,包括构造方法注入和Setter注入。
构造方法注入示例:
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<constructor-arg ref="userRepository"/>
</bean>
<bean id="userRepository" class="com.example.repository.UserRepositoryImpl"/>
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void createUser() {
userRepository.save();
}
}
Setter注入示例:
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<property name="userRepository" ref="userRepository"/>
</bean>
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void createUser() {
userRepository.save();
}
}
对比分析:
| 特性 | 构造方法注入 | Setter注入 |
|---|---|---|
| 不可变性 | 支持不可变对象 | 不支持不可变对象 |
| 强制依赖 | 更适合强制依赖 | 适合可选依赖 |
| 可读性 | 代码更清晰 | 配置较复杂 |
| 循环依赖处理 | 可能导致构造失败 | Spring可处理Setter循环依赖 |
2.2.2 注解方式实现DI
随着Spring的发展,注解方式逐渐成为主流,简化了XML配置。
示例:使用注解注入Bean
@Component
public class UserRepositoryImpl implements UserRepository {
public void save() {
System.out.println("User saved.");
}
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
public void createUser() {
userRepository.save();
}
}
配置启用组件扫描:
<context:component-scan base-package="com.example"/>
说明:
@Component:通用注解,标记为Spring管理的Bean。@Service:通常用于服务层组件。@Repository:通常用于数据访问层组件。@Autowired:自动装配依赖,默认按类型注入。@Qualifier:配合@Autowired解决类型冲突问题。
2.2.3 自动装配与组件扫描
Spring支持自动扫描和注册Bean,减少手动配置的工作量。
示例:自动装配与组件扫描
@Service
public class OrderService {
@Autowired
private PaymentService paymentService;
public void processOrder() {
paymentService.pay();
}
}
@Service
public class PaymentService {
public void pay() {
System.out.println("Payment processed.");
}
}
XML配置:
<context:component-scan base-package="com.example"/>
流程图:组件扫描与自动装配流程
graph TD
A[启动Spring容器] --> B[扫描指定包下的类]
B --> C{是否存在@Component @Service @Repository等注解?}
C -->|是| D[注册为Spring Bean]
C -->|否| E[跳过]
D --> F[自动注入依赖]
F --> G[调用Bean的方法]
2.3 面向切面编程(AOP)
2.3.1 AOP的基本概念(切面、连接点、通知等)
AOP(Aspect-Oriented Programming)是一种编程范式,旨在将横切关注点(如日志、权限、事务等)从业务逻辑中分离出来,提升代码的可重用性与可维护性。
AOP核心概念:
| 概念 | 描述 |
|---|---|
| 切面(Aspect) | 横切关注点的模块化,如日志记录、权限检查 |
| 连接点(Joinpoint) | 程序执行过程中的某个点,如方法调用 |
| 切点(Pointcut) | 定义哪些连接点将被切面影响 |
| 通知(Advice) | 切面在特定连接点上执行的动作,如前置通知、后置通知等 |
| 目标对象(Target Object) | 被代理的对象 |
| 代理(Proxy) | 生成的代理对象,负责将通知织入目标对象 |
| 织入(Weaving) | 将切面应用到目标对象并生成代理对象的过程 |
2.3.2 使用@Aspect实现日志记录与权限控制
示例:定义一个日志切面
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("Method returned: " + result);
}
}
说明:
@Aspect:声明该类为一个切面。@Component:将其注册为Spring Bean。@Before:在目标方法执行前执行。@AfterReturning:在目标方法返回后执行,可获取返回值。execution(* com.example.service.*.*(..)):表示对com.example.service包下所有类的所有方法进行拦截。
权限控制切面示例:
@Aspect
@Component
public class AuthAspect {
@Before("execution(* com.example.service.AdminService.*(..))")
public void checkPermission(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
if (!hasPermission()) {
throw new RuntimeException("No permission to execute method: " + methodName);
}
}
private boolean hasPermission() {
// 模拟权限判断逻辑
return false;
}
}
2.3.3 AOP在事务管理中的应用
Spring通过AOP实现了声明式事务管理,开发者无需在业务代码中编写事务处理逻辑。
示例:事务管理切面
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
public void createUser() {
userRepository.save();
}
}
配置启用事务管理:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
AOP在事务中的执行流程:
graph TD
A[方法调用] --> B{是否有@Transactional注解?}
B -->|是| C[开启事务]
C --> D[执行业务逻辑]
D --> E{是否抛出异常?}
E -->|是| F[回滚事务]
E -->|否| G[提交事务]
通过AOP机制,Spring实现了对事务的统一管理,提升了系统的稳定性与可维护性。
3. Spring MVC Web开发架构与流程
Spring MVC是构建Web应用的标准框架,其基于MVC设计模式,将业务逻辑、视图与控制解耦,提升开发效率与系统可维护性。
3.1 Spring MVC的基本架构
Spring MVC 是 Spring 框架中用于构建 Web 应用的核心模块。它基于经典的 MVC(Model-View-Controller)架构,将应用的控制逻辑、数据模型和用户界面进行分离,从而提高系统的可维护性和可扩展性。
3.1.1 MVC模式与Spring MVC的组件结构
MVC 是一种软件架构设计模式,主要由以下三个组件构成:
- Model(模型) :负责封装应用的数据和业务逻辑。
- View(视图) :负责展示数据,即用户界面。
- Controller(控制器) :接收用户的输入,调用模型处理数据,并将结果返回给视图。
在 Spring MVC 中,MVC 的结构具体体现为以下几个核心组件:
| 组件名称 | 职责描述 |
|---|---|
DispatcherServlet |
前端控制器,负责接收所有 HTTP 请求,并协调其他组件的调用 |
HandlerMapping |
负责将请求映射到对应的 Controller 方法 |
Controller |
处理具体的业务逻辑,并返回模型和视图信息 |
ViewResolver |
将逻辑视图名称解析为实际的视图实现(如 JSP、Thymeleaf 等) |
ModelAndView |
封装模型数据和视图信息,供 ViewResolver 使用 |
View |
渲染模型数据,生成最终的响应内容 |
Spring MVC 的整体流程可以通过如下 mermaid 流程图进行描述:
graph TD
A[客户端请求] --> B[DispatcherServlet]
B --> C[HandlerMapping]
C --> D[Controller]
D --> E[业务逻辑处理]
E --> F[ModelAndView返回]
F --> G[ViewResolver]
G --> H[实际视图渲染]
H --> I[响应返回客户端]
3.1.2 DispatcherServlet的作用与配置
DispatcherServlet 是 Spring MVC 的核心控制器,它继承自 HttpServlet ,是整个请求处理流程的起点。
作用:
- 接收所有的 HTTP 请求;
- 调用合适的 HandlerMapping 来找到对应的 Controller;
- 调用 ViewResolver 来渲染最终视图;
- 统一处理异常和文件上传等通用功能。
配置方式:
在 web.xml 中配置 DispatcherServlet :
<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-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
参数说明:
- contextConfigLocation :指定 Spring MVC 配置文件的位置;
- url-pattern 设置为 / 表示该 Servlet 处理所有请求(不包括静态资源);
- load-on-startup 设置为 1 表示容器启动时加载该 Servlet。
3.1.3 HandlerMapping与Controller的映射机制
HandlerMapping 是 Spring MVC 中用于将请求 URL 映射到具体 Controller 的组件。常用的实现类有:
BeanNameUrlHandlerMapping:根据 Controller Bean 的名称匹配 URL。SimpleUrlHandlerMapping:通过配置方式定义 URL 与 Controller 的映射关系。RequestMappingHandlerMapping:基于注解@RequestMapping的映射方式,推荐使用。
示例代码:
@Controller
public class HelloController {
@RequestMapping("/hello")
public String sayHello(Model model) {
model.addAttribute("message", "Hello, Spring MVC!");
return "hello"; // 逻辑视图名
}
}
代码解释:
- @Controller 注解表示该类是一个控制器;
- @RequestMapping("/hello") 表示访问 /hello 的请求将被该方法处理;
- Model 对象用于向视图传递数据;
- 返回值 "hello" 是逻辑视图名称,由 ViewResolver 解析为具体的视图页面(如 hello.jsp )。
HandlerMapping 的工作流程如下:
graph TD
A[HTTP请求] --> B[DispatcherServlet]
B --> C[调用HandlerMapping]
C --> D{是否存在匹配的Controller?}
D -->|是| E[调用Controller方法]
D -->|否| F[返回404错误]
3.2 请求处理流程与数据绑定
Spring MVC 的请求处理流程涵盖了从接收到请求、处理请求、绑定数据、返回响应的完整过程。该流程的高效性与灵活性,使其成为构建现代 Web 应用的理想选择。
3.2.1 请求的接收与响应的返回
Spring MVC 的请求处理流程如下:
- 客户端发送 HTTP 请求;
- 请求被
DispatcherServlet接收; DispatcherServlet根据HandlerMapping找到对应的 Controller;- Controller 执行业务逻辑;
- 返回
ModelAndView对象; ViewResolver解析视图;- 视图渲染并返回响应给客户端。
示例代码:
@RestController
public class GreetingController {
@GetMapping("/greeting")
public Greeting greet(@RequestParam(name = "name", required = false, defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
代码解释:
- @RestController 表示该 Controller 返回的是数据(如 JSON 或 XML)而非视图名称;
- @GetMapping 是 @RequestMapping(method = RequestMethod.GET) 的简化;
- @RequestParam 用于绑定请求参数;
- Greeting 是一个简单的 POJO,用于封装响应数据。
3.2.2 表单数据的绑定与验证
Spring MVC 提供了强大的数据绑定机制,能够将请求参数自动映射到 Java 对象中,并支持数据验证。
示例代码:
public class UserForm {
@NotBlank(message = "用户名不能为空")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
// getter and setter
}
@PostMapping("/register")
public String registerUser(@Valid @ModelAttribute("user") UserForm userForm, BindingResult result) {
if (result.hasErrors()) {
return "register-form";
}
// 保存用户逻辑
return "success";
}
代码解释:
- @Valid 触发数据验证;
- @ModelAttribute 将表单数据绑定到 UserForm 对象;
- BindingResult 用于捕获验证错误信息;
- 如果验证失败,返回注册页面;否则执行注册逻辑。
3.2.3 RESTful风格的接口设计
RESTful 是一种基于 HTTP 方法(GET、POST、PUT、DELETE)的接口设计风格,Spring MVC 对其有良好的支持。
示例代码:
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.findUserById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.saveUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
}
代码解释:
- @RestController 表示返回 JSON 数据;
- @RequestMapping 定义基础路径 /api/users ;
- @GetMapping("/{id}") 表示 GET 请求,路径参数 id 使用 @PathVariable 接收;
- @RequestBody 表示将请求体中的 JSON 映射为 Java 对象;
- ResponseEntity 可以灵活控制 HTTP 状态码和响应体。
3.3 视图解析与异常处理
Spring MVC 支持多种视图技术,如 JSP、Thymeleaf、Freemarker 等。同时,它也提供了统一的异常处理机制,使得开发者可以集中管理错误响应。
3.3.1 Thymeleaf与JSP视图技术对比
| 特性 | Thymeleaf | JSP |
|---|---|---|
| 模板语法 | HTML5 兼容,支持自然语言模板 | JSP 语法,需编译成 Servlet |
| 性能 | 略低(首次渲染较慢) | 较高(预编译优化) |
| 适用场景 | Web 页面渲染、邮件模板、静态内容生成 | 传统 Web 项目,适合动态页面渲染 |
| 与 Spring 整合 | 原生支持,推荐使用 | 支持良好,但配置较繁琐 |
| 开发调试 | 支持静态 HTML 直接查看,易于调试 | 需运行服务器才能查看效果 |
Thymeleaf 示例:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
</head>
<body>
<h1 th:text="${message}">Default Message</h1>
</body>
</html>
Spring MVC 配置 Thymeleaf:
@Configuration
public class ThymeleafConfig {
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
@Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.setTemplateResolver(templateResolver());
return engine;
}
@Bean
public ITemplateResolver templateResolver() {
WebApplicationTemplateResolver resolver = new WebApplicationTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
3.3.2 全局异常处理器的实现
Spring MVC 提供了 @ControllerAdvice 和 @ExceptionHandler 注解,用于统一处理异常。
示例代码:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("资源未找到");
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
}
代码解释:
- @ControllerAdvice 表示这是一个全局异常处理器;
- @ExceptionHandler 用于定义具体的异常处理方法;
- 返回 ResponseEntity 可以自定义响应状态码和内容。
3.3.3 国际化消息支持与多语言配置
Spring MVC 支持通过 MessageSource 实现多语言支持。
配置步骤:
-
创建多个消息文件,如:
- messages_en.properties
- messages_zh_CN.properties -
配置
MessageSource:
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.US);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
使用方式:
@Autowired
private MessageSource messageSource;
public String getLocalizedMessage(Locale locale) {
return messageSource.getMessage("welcome.message", null, locale);
}
说明:
- 用户可通过请求参数 lang=en 或 lang=zh_CN 切换语言;
- LocaleResolver 用于确定当前请求的语言环境;
- MessageSource 用于读取对应的多语言信息。
以上内容完整覆盖了 Spring MVC 的核心架构、请求处理流程、视图解析与异常处理机制,并结合代码示例、流程图、对比表格等形式,详细阐述了每个子模块的功能与实现方式,满足从基础理解到实践操作的递进式学习需求。
4. Spring Boot自动配置与内嵌服务器
Spring Boot 是 Spring 生态中最具代表性的项目之一,它通过 自动配置机制 和 内嵌服务器 大大简化了项目的配置和部署流程。本章将深入探讨 Spring Boot 的核心特性,包括其自动配置机制的实现原理、Starter 依赖的工作方式,以及内嵌服务器(如 Tomcat、Jetty、Undertow)的配置与部署方法。
4.1 Spring Boot快速入门
Spring Boot 以其“开箱即用”的特性迅速成为 Java Web 开发的首选框架。它不仅简化了传统 Spring 应用的配置流程,还提供了快速启动和部署的能力。
4.1.1 Spring Boot的核心优势与项目结构
Spring Boot 的核心优势包括:
| 优势 | 描述 |
|---|---|
| 自动配置 | 根据类路径中的依赖自动配置 Spring 容器 |
| 内嵌服务器 | 无需外部部署服务器即可运行 Web 应用 |
| 起步依赖(Starter) | 简化依赖管理,通过一个依赖引入一组相关库 |
| 生产就绪 | 提供健康检查、指标监控、外部配置等功能 |
Spring Boot 项目的标准目录结构如下:
src
├── main
│ ├── java
│ │ └── com.example.demo
│ │ ├── DemoApplication.java // 主类
│ │ └── controller // 控制器类
│ │ └── HelloController.java
│ │ └── service // 服务类
│ │ └── repository // 数据访问类
│ ├── resources
│ ├── application.properties // 配置文件
│ └── static // 静态资源
│ └── templates // 模板资源
└── test
└── java
└── com.example.demo
└── DemoApplicationTests.java
4.1.2 使用Spring Initializr创建项目
Spring Initializr 是 Spring 官方提供的项目生成器,访问地址:https://start.spring.io/
步骤如下:
- 选择项目类型(Maven/Gradle)
- 选择语言(Java/Kotlin/Scala)
- 选择 Spring Boot 版本
- 添加依赖(如 Spring Web、Spring Data JPA、Thymeleaf 等)
- 点击“Generate”下载项目压缩包
示例依赖配置(Maven):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
4.1.3 主类与启动流程分析
Spring Boot 的主类使用 @SpringBootApplication 注解,它是组合注解,包含以下三个核心注解:
@SpringBootConfiguration:标识当前类为配置类@ComponentScan:启用组件扫描@EnableAutoConfiguration:启用自动配置机制
主类示例:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
执行 SpringApplication.run() 后的流程如下:
graph TD
A[SpringApplication.run] --> B[加载主类]
B --> C[创建ApplicationContext]
C --> D[执行自动配置]
D --> E[注册Bean]
E --> F[启动内嵌服务器]
F --> G[监听端口并处理请求]
4.2 自动配置原理与Starter机制
Spring Boot 的自动配置机制是其最核心的特性之一,使得开发者无需手动配置大量 Bean,即可快速构建应用。
4.2.1 自动配置类的加载与条件判断
Spring Boot 的自动配置类通常以 *AutoConfiguration 结尾,并位于 spring-boot-autoconfigure 模块中。例如:
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedServletContainerCustomizer.class})
public class DataSourceAutoConfiguration {
...
}
自动配置类中广泛使用了 @ConditionalOnXxx 注解来控制配置的加载条件,例如:
| 注解 | 作用 |
|---|---|
@ConditionalOnClass |
某个类在类路径中存在时才加载配置 |
@ConditionalOnMissingClass |
某个类不在类路径中才加载配置 |
@ConditionalOnBean |
容器中存在某个 Bean 时加载配置 |
@ConditionalOnMissingBean |
容器中不存在某个 Bean 时加载配置 |
@ConditionalOnProperty |
配置文件中某个属性存在时加载配置 |
这些注解确保了自动配置只在需要时生效,避免不必要的资源浪费。
4.2.2 Starter依赖的原理与自定义Starter
Spring Boot 的 Starter 是一种约定优于配置的设计,每个 Starter 都封装了特定功能所需的依赖和默认配置。
Starter 的组成:
- 依赖管理 :Maven
pom.xml或 Gradlebuild.gradle中声明相关依赖 - 自动配置类 :位于
META-INF/spring.factories文件中 - 属性配置类 :用于绑定
application.yml中的配置项
示例:创建一个自定义 Starter my-spring-boot-starter
-
创建 Maven 项目
my-spring-boot-starter -
添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
- 编写自动配置类:
@Configuration
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService("Hello from MyStarter");
}
}
- 在
src/main/resources/META-INF/spring.factories中注册自动配置类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.mystarter.MyAutoConfiguration
- 使用方式:
在目标项目中引入:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
然后注入并使用:
@RestController
public class MyController {
@Autowired
private MyService myService;
@GetMapping("/hello")
public String sayHello() {
return myService.getMessage();
}
}
4.2.3 配置文件application.yml的使用
Spring Boot 支持 application.properties 和 application.yml 两种配置方式。YAML 格式更结构化,适合嵌套配置。
示例 application.yml :
server:
port: 8081
spring:
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
读取配置类示例:
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
private String driverClassName;
// Getters and Setters
}
Spring Boot 会自动将 spring.datasource 下的配置映射到该类的字段中。
4.3 内嵌服务器与外部部署
Spring Boot 支持多种内嵌服务器,开发者可根据项目需求灵活选择。
4.3.1 Tomcat、Jetty与Undertow的对比
| 特性 | Tomcat | Jetty | Undertow |
|---|---|---|---|
| 默认服务器 | 是 | 否 | 否 |
| 性能 | 中等 | 高 | 高 |
| 易用性 | 高 | 中等 | 中等 |
| 异步支持 | 支持 | 支持 | 强支持 |
| 启动速度 | 中等 | 快 | 快 |
在 pom.xml 中切换内嵌服务器:
- 排除 Tomcat :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 添加 Undertow :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
- 添加 Jetty :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
4.3.2 外置Tomcat的部署方式
虽然内嵌服务器方便开发,但生产环境通常使用外置 Tomcat。以下是部署步骤:
- 修改
pom.xml,将打包方式改为war:
<packaging>war</packaging>
- 排除内嵌 Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 修改主类继承
SpringBootServletInitializer:
public class DemoApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 执行 Maven 打包:
mvn clean package
生成的 target/demo-0.0.1-SNAPSHOT.war 可部署到 Tomcat 的 webapps 目录下。
4.3.3 生产环境的配置优化
为了提升 Spring Boot 应用在生产环境的性能和安全性,可以进行如下优化:
| 优化项 | 配置示例 |
|---|---|
| 日志级别控制 | logging.level.root=INFO |
| 缓存配置 | spring.cache.type=SIMPLE |
| 数据库连接池 | spring.datasource.hikari.maximum-pool-size=10 |
| 启用HTTPS | 配置 SSL 证书,使用 server.ssl.enabled=true |
| 禁用调试端点 | management.endpoints.web.exposure.include=health,info |
| 启用Gzip压缩 | server.compression.enabled=true |
生产环境建议使用配置文件 application-prod.yml ,并通过 spring.profiles.active=prod 指定激活环境。
本章从 Spring Boot 的快速入门入手,逐步讲解了其自动配置机制、Starter 依赖的构建原理,以及内嵌服务器的配置与部署方式。下一章将深入探讨 MyBatis 框架的 ORM 映射机制与数据库操作实践。
5. MyBatis ORM映射与数据库操作
5.1 MyBatis基础与核心接口
5.1.1 ORM的概念与MyBatis的优势
ORM(Object-Relational Mapping,对象关系映射)是一种编程技术,用于在面向对象语言中自动将数据库表映射为对象。通过ORM,开发者可以避免直接编写SQL语句,而是通过对象操作数据库,提升开发效率和代码可维护性。
MyBatis作为轻量级的ORM框架,相较于Hibernate等全自动ORM框架,具有更高的灵活性。它允许开发者编写原生SQL语句,并通过映射文件或注解将SQL结果集映射到Java对象中,适用于需要对SQL进行细粒度控制的场景。
MyBatis的主要优势包括:
1. 灵活的SQL控制 :开发者可以编写原生SQL语句,便于优化查询性能。
2. 轻量级与可集成性 :MyBatis不依赖特定的容器,可轻松集成到Spring等主流框架中。
3. 支持动态SQL :通过 <if> 、 <choose> 、 <foreach> 等标签,动态构建SQL语句,提高SQL复用性。
4. 缓存机制 :支持一级缓存(SqlSession级别)和二级缓存(Mapper级别),减少数据库访问频率。
与其他ORM框架相比,如Hibernate和JPA,MyBatis更适用于对SQL性能有高要求、需要灵活控制SQL的项目场景。
| ORM框架 | 特点 | 适用场景 |
|---|---|---|
| Hibernate | 全自动ORM,自动生成SQL | 快速开发、对SQL控制要求不高 |
| JPA | 基于Hibernate,标准化的Java ORM规范 | 企业级应用开发 |
| MyBatis | 半自动ORM,需手动编写SQL | 需要灵活控制SQL、性能优化 |
5.1.2 SqlSessionFactory与SqlSession的作用
在MyBatis中,核心接口包括 SqlSessionFactory 和 SqlSession ,它们负责管理数据库连接和执行SQL语句。
- SqlSessionFactory
SqlSessionFactory是一个工厂类,用于创建SqlSession实例。它通常在应用启动时构建一次,并在整个生命周期中保持不变。构建方式如下:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
其中 mybatis-config.xml 是MyBatis的全局配置文件,用于定义数据库连接、事务管理器、映射文件路径等。
- SqlSession
SqlSession是MyBatis的核心接口,用于执行SQL语句并获取结果。每个线程应独立使用一个SqlSession实例,以避免并发问题。基本使用方式如下:
try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
}
上述代码中, session.getMapper() 方法会返回一个动态代理对象,该对象封装了具体的SQL执行逻辑。
逻辑分析 :
1. SqlSessionFactory 通过解析配置文件创建数据库连接池。
2. SqlSession 在调用 getMapper() 时,会根据接口定义的注解或XML文件中的SQL语句生成动态代理对象。
3. 代理对象在执行方法时,会调用底层的 Executor 执行SQL,并将结果映射到Java对象。
5.1.3 Mapper接口与XML映射文件的绑定
MyBatis通过 Mapper 接口与XML映射文件绑定,实现SQL语句与Java对象的映射。
- Mapper接口
Mapper接口是一个普通的Java接口,其中定义的方法与XML文件中的SQL语句一一对应。例如:
public interface UserMapper {
User selectUserById(int id);
}
- XML映射文件
XML文件中定义SQL语句及其映射关系,示例如下:
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
其中 namespace 属性对应 UserMapper 接口的全限定名, id 属性对应接口方法名, resultType 指定返回值类型。
绑定机制流程图 (使用mermaid语法):
graph TD
A[Mapper接口] --> B{MyBatis代理机制}
B --> C[解析接口方法]
C --> D[查找XML映射文件中的SQL]
D --> E[执行SQL并映射结果]
E --> F[返回Java对象]
代码逻辑分析 :
1. 接口方法 selectUserById(int id) 被调用时,MyBatis通过动态代理机制生成实现类。
2. 代理类会查找对应XML文件中 id 为 selectUserById 的SQL语句。
3. SQL语句中的 #{id} 表示参数占位符,MyBatis会将其替换为方法传入的 id 值。
4. SQL执行后,MyBatis将结果集映射到 com.example.model.User 类型的对象并返回。
5.2 SQL映射与结果处理
5.2.1 简单查询与动态SQL的使用
MyBatis支持简单的SQL查询和复杂的动态SQL语句构建。动态SQL通过 <if> 、 <choose> 、 <when> 、 <set> 、 <foreach> 等标签实现。
简单查询示例
<select id="findUserByName" resultType="com.example.model.User">
SELECT * FROM users WHERE name = #{name}
</select>
动态SQL示例
<select id="searchUsers" resultType="com.example.model.User">
SELECT * FROM users
<where>
<if test="name != null">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="age != null">
AND age >= #{age}
</if>
</where>
</select>
逻辑分析 :
- <where> 标签会自动去除开头的 AND 或 OR ,避免SQL语法错误。
- <if> 标签根据条件判断是否添加对应的查询条件。
代码调用示例 :
List<User> users = userMapper.searchUsers("Tom", 25);
5.2.2 结果集映射与嵌套查询
MyBatis支持复杂的结果集映射,包括一对一、一对多等嵌套查询。
一对一映射示例
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<association property="address" columnPrefix="addr_" javaType="com.example.model.Address">
<id property="id" column="id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
</association>
</resultMap>
<select id="selectUserWithAddress" resultMap="userResultMap">
SELECT u.id, u.name, a.street addr_street, a.city addr_city
FROM users u
LEFT JOIN addresses a ON u.address_id = a.id
WHERE u.id = #{id}
</select>
逻辑分析 :
- <resultMap> 定义了结果集映射规则。
- <association> 表示关联对象,用于映射一对一关系。
- columnPrefix 属性用于区分主表和关联表的字段前缀。
一对多映射示例
<resultMap id="userWithOrders" type="com.example.model.User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<collection property="orders" ofType="com.example.model.Order">
<id property="orderId" column="order_id"/>
<result property="amount" column="amount"/>
</collection>
</resultMap>
<select id="selectUserWithOrders" resultMap="userWithOrders">
SELECT u.id, u.name, o.order_id, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
逻辑分析 :
- <collection> 用于映射一对多关系, ofType 指定集合元素类型。
- SQL语句中通过 LEFT JOIN 获取用户的所有订单。
5.2.3 缓存机制与性能优化
MyBatis支持一级缓存和二级缓存,以提高数据库查询性能。
- 一级缓存 (SqlSession级别):默认开启,同一个
SqlSession内多次执行相同查询,结果会被缓存。 - 二级缓存 (Mapper级别):多个
SqlSession可以共享缓存,需手动开启。
开启二级缓存
在Mapper XML文件中添加 <cache> 标签:
<mapper namespace="com.example.mapper.UserMapper">
<cache/>
...
</mapper>
同时在 mybatis-config.xml 中启用二级缓存:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
性能优化建议 :
1. 对于频繁查询但不常变化的数据,建议启用二级缓存。
2. 避免缓存穿透,可使用空值缓存或布隆过滤器。
3. 使用缓存时注意数据一致性,可通过定时刷新或事件驱动更新缓存。
5.3 整合Spring与事务管理
5.3.1 在Spring中集成MyBatis
Spring与MyBatis的整合通过 mybatis-spring 模块实现。主要步骤包括:
- 引入依赖
在pom.xml中添加Spring与MyBatis整合依赖:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
- 配置数据源与SqlSessionFactory
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
- 配置Mapper扫描器
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper"/>
</bean>
逻辑分析 :
- SqlSessionFactoryBean 用于创建 SqlSessionFactory ,并绑定数据源。
- MapperScannerConfigurer 会自动扫描指定包下的 Mapper 接口,并为其生成代理类。
5.3.2 使用Spring管理事务
Spring通过 @Transactional 注解实现声明式事务管理。
使用方式 :
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void transferMoney(int fromId, int toId, double amount) {
userMapper.deductBalance(fromId, amount);
userMapper.addBalance(toId, amount);
}
}
逻辑分析 :
- @Transactional 注解的方法会在事务上下文中执行。
- 如果方法执行过程中发生异常,事务将自动回滚。
- Spring使用AOP技术实现事务管理,底层依赖 PlatformTransactionManager 。
5.3.3 多数据源的配置与使用
在实际项目中,可能会使用多个数据库,此时需要配置多个数据源。
配置方式 (使用XML配置):
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db1"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db2"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1"/>
<property name="mapperLocations" value="classpath:mapper/db1/*.xml"/>
</bean>
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2"/>
<property name="mapperLocations" value="classpath:mapper/db2/*.xml"/>
</bean>
使用方式 :
@Service
public class MultiDataSourceService {
@Autowired
private UserMapper userMapper1;
@Autowired
private OrderMapper orderMapper2;
public void process() {
// 使用第一个数据源
userMapper1.selectUserById(1);
// 使用第二个数据源
orderMapper2.selectOrderById(1001);
}
}
逻辑分析 :
- 不同的 SqlSessionFactory 绑定不同的数据源和映射文件。
- 通过自动注入不同 Mapper 接口,实现多数据源访问。
- 实际项目中,还可以使用 AbstractRoutingDataSource 实现动态数据源切换。
6. 全栈项目整合开发与部署实战
6.1 项目需求分析与技术选型
6.1.1 项目背景与功能模块划分
本项目为一个典型的“企业员工管理系统”,主要功能包括:
- 员工信息管理(增删改查)
- 部门管理(部门信息维护)
- 权限控制(基于角色的访问控制)
- 登录认证与 Token 机制(JWT)
系统采用前后端分离架构,后端使用 Spring Boot + MyBatis + MySQL,前端使用 Vue3 + Element Plus,部署使用 Docker + Nginx。
6.1.2 技术栈选择与架构设计
| 层级 | 技术栈 |
|---|---|
| 后端框架 | Spring Boot 2.7.x |
| ORM 框架 | MyBatis Plus |
| 数据库 | MySQL 8.0 |
| 前端框架 | Vue 3 + Element Plus |
| 接口文档 | Swagger UI + Knife4j |
| 部署方式 | Docker + Nginx |
| 持续集成 | Jenkins / GitHub Actions |
6.1.3 接口文档设计与Mock数据准备
使用 Swagger UI 生成接口文档,接口风格统一 RESTful。例如:
GET /api/employees
响应示例:
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"department": "研发部"
}
]
}
前端使用 Mock.js 或 JSON Server 模拟接口响应,确保前后端开发并行推进。
6.2 后端服务开发与测试
6.2.1 基于Spring Boot构建RESTful API
使用 Spring Boot 创建 RESTful 风格接口,以 EmployeeController 为例:
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping
public ResponseEntity<List<Employee>> getAllEmployees() {
return ResponseEntity.ok(employeeService.getAllEmployees());
}
@PostMapping
public ResponseEntity<Employee> createEmployee(@RequestBody Employee employee) {
return ResponseEntity.status(HttpStatus.CREATED).body(employeeService.saveEmployee(employee));
}
}
参数说明:
@RestController:表示该类的每个方法返回的数据直接写入 HTTP 响应体中。@RequestMapping:设置基础路径。@GetMapping:映射 GET 请求。@PostMapping:映射 POST 请求。ResponseEntity:用于构建带有状态码的响应。
6.2.2 数据库设计与MyBatis实现CRUD
数据库表结构如下:
CREATE TABLE employee (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100),
department_id BIGINT
);
使用 MyBatis Plus 实现数据访问层:
public interface EmployeeMapper extends BaseMapper<Employee> {
}
Service 层实现逻辑:
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public List<Employee> getAllEmployees() {
return employeeMapper.selectList(null);
}
public Employee saveEmployee(Employee employee) {
employeeMapper.insert(employee);
return employee;
}
}
6.2.3 接口测试与Swagger文档生成
添加依赖:
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
配置 Swagger:
@Configuration
@EnableOpenApi
@EnableKnife4j
public class SwaggerConfig {
}
访问 http://localhost:8080/doc.html 即可查看接口文档并进行测试。
6.3 前端页面开发与交互实现
6.3.1 Vue项目搭建与组件划分
使用 Vue CLI 创建项目:
vue create employee-system
cd employee-system
npm install element-plus axios vue-router
组件结构如下:
src/
├── components/
│ ├── EmployeeList.vue
│ ├── EmployeeForm.vue
├── views/
│ ├── HomeView.vue
│ ├── LoginView.vue
├── router/index.js
├── App.vue
└── main.js
6.3.2 Axios调用后端接口与状态管理
封装 Axios 请求:
// src/utils/request.js
import axios from 'axios';
const service = axios.create({
baseURL: 'http://localhost:8080',
timeout: 5000
});
export default service;
调用接口:
// src/api/employee.js
import request from '@/utils/request';
export function getEmployees() {
return request.get('/api/employees');
}
export function createEmployee(data) {
return request.post('/api/employees', data);
}
6.3.3 路由管理与权限控制实现
配置路由:
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView,
meta: { requiresAuth: true }
},
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 路由守卫
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token');
if (to.meta.requiresAuth && !token) {
next('/login');
} else {
next();
}
});
export default router;
6.4 项目部署与持续集成
6.4.1 使用Docker打包后端服务与MySQL
Dockerfile 示例:
FROM openjdk:17-jdk-slim
COPY *.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
MySQL 容器启动命令:
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /mydata/mysql/data:/var/lib/mysql \
mysql:8.0
启动后端服务容器:
docker build -t employee-system .
docker run -d -p 8080:8080 --name app employee-system
6.4.2 Nginx反向代理与静态资源托管
Nginx 配置示例:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ =404;
}
location /api {
proxy_pass http://localhost:8080;
}
}
将 Vue 项目打包并上传至 Nginx 的 html 目录:
npm run build
cp -r dist/* /usr/share/nginx/html/
6.4.3 Git提交规范与CI/CD流程配置
使用 Git 提交规范(Conventional Commits):
feat: add search functionality
fix: resolve login token issue
chore: update dependencies
使用 GitHub Actions 实现 CI/CD:
name: Spring Boot CI/CD
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Build with Maven
run: mvn clean package
- name: Build Docker Image
run: |
docker build -t employee-system .
docker save employee-system > employee.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: employee-app
path: employee.tar
(本章节内容到此结束,下一章节将围绕性能优化与日志监控展开。)
简介:本学习笔记合集涵盖全栈开发关键技术,包括Java编程语言、Spring框架体系、MyBatis持久层、Vue前端开发、MySQL与MongoDB数据库、Redis缓存、Docker容器化部署及Nginx服务器配置等内容。适合初学者系统学习或开发者日常查阅使用,帮助掌握现代Web应用开发所需的完整技术栈,提升实战能力与项目部署效率。
更多推荐



所有评论(0)