本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本学习笔记合集涵盖全栈开发关键技术,包括Java编程语言、Spring框架体系、MyBatis持久层、Vue前端开发、MySQL与MongoDB数据库、Redis缓存、Docker容器化部署及Nginx服务器配置等内容。适合初学者系统学习或开发者日常查阅使用,帮助掌握现代Web应用开发所需的完整技术栈,提升实战能力与项目部署效率。
学习笔记::books:JAVA,Spring,SpringMVC,SpringBoot,Mybatis,Vue,MySQL,MongoDB,Radis,Docker,Nginx,......笔记

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容器主要有两种实现方式:

  1. BeanFactory :是Spring最基础的IoC容器,提供基本的依赖注入功能,延迟加载(Lazy Loading)是其特点。
  2. 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>
代码逻辑分析:
  1. ApplicationContext 从指定路径加载XML配置文件。
  2. Spring容器根据配置文件创建 UserService UserRepository 两个Bean。
  3. UserService Bean通过 property 标签注入了 UserRepository Bean。
  4. 最终通过 getBean 方法获取并调用 UserService 的方法。

这种将对象的创建和管理交给容器的方式,使得组件之间的耦合度大大降低,提升了系统的可测试性和可维护性。

2.1.3 Bean的生命周期与作用域

Spring中的Bean具有不同的生命周期阶段和作用域,理解这些概念对于开发高质量的Spring应用至关重要。

Bean的生命周期阶段:
  1. 实例化 :Spring容器通过反射创建Bean实例。
  2. 属性注入 :容器将配置中定义的属性值或依赖对象注入到Bean中。
  3. 初始化方法调用 :如果Bean实现了 InitializingBean 接口或配置了 init-method ,则调用初始化方法。
  4. 使用阶段 :Bean可以被应用程序使用。
  5. 销毁方法调用 :当容器关闭时,如果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 的请求处理流程如下:

  1. 客户端发送 HTTP 请求;
  2. 请求被 DispatcherServlet 接收;
  3. DispatcherServlet 根据 HandlerMapping 找到对应的 Controller;
  4. Controller 执行业务逻辑;
  5. 返回 ModelAndView 对象;
  6. ViewResolver 解析视图;
  7. 视图渲染并返回响应给客户端。

示例代码:

@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 实现多语言支持。

配置步骤:

  1. 创建多个消息文件,如:
    - messages_en.properties
    - messages_zh_CN.properties

  2. 配置 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/

步骤如下:

  1. 选择项目类型(Maven/Gradle)
  2. 选择语言(Java/Kotlin/Scala)
  3. 选择 Spring Boot 版本
  4. 添加依赖(如 Spring Web、Spring Data JPA、Thymeleaf 等)
  5. 点击“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 或 Gradle build.gradle 中声明相关依赖
  • 自动配置类 :位于 META-INF/spring.factories 文件中
  • 属性配置类 :用于绑定 application.yml 中的配置项

示例:创建一个自定义 Starter my-spring-boot-starter

  1. 创建 Maven 项目 my-spring-boot-starter

  2. 添加依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>
  1. 编写自动配置类:
@Configuration
public class MyAutoConfiguration {
    @Bean
    public MyService myService() {
        return new MyService("Hello from MyStarter");
    }
}
  1. src/main/resources/META-INF/spring.factories 中注册自动配置类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.mystarter.MyAutoConfiguration
  1. 使用方式:

在目标项目中引入:

<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。以下是部署步骤:

  1. 修改 pom.xml ,将打包方式改为 war
<packaging>war</packaging>
  1. 排除内嵌 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>
  1. 修改主类继承 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);
    }
}
  1. 执行 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 模块实现。主要步骤包括:

  1. 引入依赖
    pom.xml 中添加Spring与MyBatis整合依赖:
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>
  1. 配置数据源与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>
  1. 配置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

(本章节内容到此结束,下一章节将围绕性能优化与日志监控展开。)

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本学习笔记合集涵盖全栈开发关键技术,包括Java编程语言、Spring框架体系、MyBatis持久层、Vue前端开发、MySQL与MongoDB数据库、Redis缓存、Docker容器化部署及Nginx服务器配置等内容。适合初学者系统学习或开发者日常查阅使用,帮助掌握现代Web应用开发所需的完整技术栈,提升实战能力与项目部署效率。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

更多推荐