Spring Boot 学习:原理、注解、配置文件与部署解析

Spring Boot 学习:原理、注解、配置文件与部署解析

一、Spring Boot 核心定位与价值

Spring Boot 是由 Pivotal 团队(后归属于 VMware)基于 Spring Framework 开发的轻量级、约定大于配置的快速开发框架,核心目标是:

消除 Spring 框架繁琐的 XML / 注解配置,降低入门门槛;

简化依赖管理,解决 "依赖地狱" 问题;

提供一站式的企业级应用开发能力,快速构建独立、可运行的应用;

无缝集成 Spring 生态(Spring MVC、Spring Data、Spring Security 等)。

核心价值:让开发者从 "配置繁琐" 中解放,聚焦业务逻辑开发,实现 "开箱即用、快速迭代"。


二、Spring Boot 核心架构与核心组件

1. 核心架构(极简版)
2. 核心组件详解
(1)核心注解:@SpringBootApplication

这是 Spring Boot 最核心的注解,是一个 "组合注解",包含 3 个关键注解:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 1. 核心:开启自动配置
@EnableAutoConfiguration
// 2. 扫描当前包及子包下的@Component/@Controller/@Service等注解
@ComponentScan
// 3. 标记当前类为配置类,可定义@Bean
@Configuration
public @interface SpringBootApplication {
    // 排除特定自动配置类
    Class<?>[] exclude() default {};
}

@EnableAutoConfiguration:触发自动配置核心逻辑,是 Spring Boot "约定大于配置" 的核心;

@ComponentScan :替代传统 Spring 的 <context:component-scan>,自动扫描组件;

@Configuration :替代传统 Spring 的 XML 配置文件,支持通过 @Bean 定义组件。

(2)自动配置(AutoConfiguration)

Spring Boot 最核心的特性,底层基于Spring 条件注解(@Conditional) 实现:

原理 :启动时,Spring Boot 会扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,加载所有自动配置类(如 WebMvcAutoConfigurationDataSourceAutoConfiguration);

逻辑 :每个自动配置类通过 @ConditionalOnClass(类存在时生效)、@ConditionalOnMissingBean(Bean 不存在时生效)等注解,判断是否需要自动配置组件;

示例 :引入 spring-boot-starter-web 依赖后,WebMvcAutoConfiguration 会自动配置 DispatcherServlet、视图解析器、JSON 转换器等,无需手动配置。

(3)起步依赖(Starter Dependencies)

Spring Boot 将常用的依赖组合打包成 "启动器",解决依赖版本冲突、手动引入漏项问题:

核心设计:每个 Starter 都有一个 pom.xml,包含该场景下所有必需的依赖,且版本由 Spring Boot 父工程(spring-boot-starter-parent)统一管理;

常用 Starter:

Starter 名称 用途 核心依赖
spring-boot-starter-web Web 开发(RESTful API) Spring MVC、Tomcat、Jackson
spring-boot-starter-data-jpa 数据库操作(JPA/ORM) Hibernate、Spring Data JPA
spring-boot-starter-data-redis Redis 操作 Lettuce/Jedis、Spring Data Redis
spring-boot-starter-security 安全认证(权限 / 登录) Spring Security
spring-boot-starter-test 单元测试 JUnit、Mockito、AssertJ
spring-boot-starter-actuator 应用监控 Actuator 核心组件
(4)内嵌服务器

Spring Boot 内置 Tomcat(默认)、Jetty、Undertow 等 Web 服务器,无需外部部署:

原理:通过 spring-boot-starter-web 引入 tomcat-embed-core 等依赖,启动时通过 SpringApplication 自动启动内嵌服务器;

切换服务器:排除 Tomcat 依赖,引入 Jetty/Undertow 即可:

xml 复制代码
<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>
<!-- 引入 Jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
(5)配置管理体系

Spring Boot 支持多维度配置,优先级从高到低:

  1. 命令行参数(--server.port=8081);
  2. 操作系统环境变量;
  3. 应用外部配置文件(如 ./config/application.yml);
  4. 应用内部配置文件(src/main/resources/application.yml);
  5. 自动配置默认值。

支持的配置格式:propertiesyamljson(推荐 yaml,支持复杂结构)。


三、Spring Boot 工程结构(最佳实践)

规范的工程结构能提升可维护性,以下是企业级项目的标准结构:

plaintext 复制代码
com.example.demo/
├── DemoApplication.java          # 启动类(必须放在根包下)
├── config/                       # 自定义配置类
│   ├── MyBatisConfig.java        # MyBatis 配置
│   └── SecurityConfig.java       # 安全配置
├── controller/                   # 控制器(API 入口)
│   ├── UserController.java
│   └── OrderController.java
├── service/                      # 业务逻辑层
│   ├── impl/                     # 实现类
│   │   ├── UserServiceImpl.java
│   │   └── OrderServiceImpl.java
│   ├── UserService.java          # 接口
│   └── OrderService.java
├── mapper/                       # 数据访问层(MyBatis/Mapper)
│   ├── UserMapper.java
│   └── OrderMapper.java
├── repository/                   # 数据访问层(JPA/Repository)
│   ├── UserRepository.java
│   └── OrderRepository.java
├── entity/                       # 实体类(POJO/DO/DTO/VO)
│   ├── User.java
│   └── Order.java
├── exception/                    # 自定义异常
│   ├── BusinessException.java
│   └── GlobalExceptionHandler.java # 全局异常处理
├── util/                         # 工具类
│   ├── DateUtil.java
│   └── HttpUtil.java
└── resources/                    # 资源目录
    ├── application.yml           # 主配置文件
    ├── application-dev.yml       # 开发环境配置
    ├── application-prod.yml      # 生产环境配置
    ├── mapper/                   # MyBatis 映射文件
    │   ├── UserMapper.xml
    │   └── OrderMapper.xml
    ├── static/                   # 静态资源(CSS/JS/图片)
    └── templates/                # 模板文件(Thymeleaf/Freemarker)

工程分层架构图


四、Spring Boot 核心开发流程

以开发一个 "用户管理" RESTful API 为例,完整流程如下:

1. 环境准备

JDK 11/17(推荐 LTS 版本);

Maven/Gradle(构建工具);

IDE(IntelliJ IDEA);

Spring Boot 3.2.x(稳定版)。

2. 创建项目(Spring Initializr)

访问 https://start.spring.io/:

选择:Maven → Java → Spring Boot 3.2.x;

Group:com.example,Artifact:user-demo

勾选依赖:Spring WebSpring Data JPAMySQL Driver

下载项目,解压后用 IDE 打开。

3. 核心开发步骤
步骤 1:配置数据库(application-dev.yml)
yaml 复制代码
spring:
  profiles: dev
  datasource:
    url: jdbc:mysql://localhost:3306/user_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update # 自动创建/更新表结构
    show-sql: true     # 打印SQL语句
    properties:
      hibernate:
        format_sql: true # 格式化SQL
server:
  port: 8080
步骤 2:创建实体类(User.java)
java 复制代码
package com.example.userdemo.entity;

import jakarta.persistence.*;
import lombok.Data;

@Data // Lombok 注解,自动生成getter/setter
@Entity // JPA 实体注解
@Table(name = "t_user") // 对应数据库表名
public class User {
    @Id // 主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
    private Long id;
    
    @Column(name = "username", unique = true, nullable = false) // 列属性
    private String username;
    
    @Column(name = "password", nullable = false)
    private String password;
    
    @Column(name = "email")
    private String email;
}
步骤 3:创建 Repository(数据访问层)
java 复制代码
package com.example.userdemo.repository;

import com.example.userdemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

// JpaRepository<实体类, 主键类型> 提供CRUD、分页等默认方法
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // 自定义查询:根据用户名查询用户
    User findByUsername(String username);
}
步骤 4:创建 Service(业务逻辑层)
java 复制代码
// 接口
package com.example.userdemo.service;

import com.example.userdemo.entity.User;
import java.util.List;

public interface UserService {
    User saveUser(User user);
    User getUserById(Long id);
    User getUserByUsername(String username);
    List<User> getAllUsers();
    void deleteUser(Long id);
}

// 实现类
package com.example.userdemo.service.impl;

import com.example.userdemo.entity.User;
import com.example.userdemo.repository.UserRepository;
import com.example.userdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User saveUser(User user) {
        return userRepository.save(user);
    }

    @Override
    public User getUserById(Long id) {
        // orElseThrow:不存在则抛异常
        return userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }

    @Override
    public User getUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @Override
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}
步骤 5:创建 Controller(API 层)
java 复制代码
package com.example.userdemo.controller;

import com.example.userdemo.entity.User;
import com.example.userdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController // @Controller + @ResponseBody
@RequestMapping("/api/users") // 统一前缀
public class UserController {

    @Autowired
    private UserService userService;

    // 新增用户:POST请求
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.saveUser(user);
    }

    // 根据ID查询用户:GET请求
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    // 查询所有用户:GET请求
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    // 删除用户:DELETE请求
    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return "删除成功";
    }
}
步骤 6:启动应用并测试

运行 UserDemoApplicationmain 方法;

使用 Postman / 浏览器测试 API:

新增用户:POST http://localhost:8080/api/users,请求体(JSON):

json 复制代码
{
    "username": "zhangsan",
    "password": "123456",
    "email": "zhangsan@example.com"
}

查询所有用户:GET http://localhost:8080/api/users

查询单个用户:GET http://localhost:8080/api/users/1


五、Spring Boot 高级特性

1. 多环境配置

方式 1:拆分文件(推荐):

application-dev.yml(开发)、application-test.yml(测试)、application-prod.yml(生产);

激活环境:spring.profiles.active=prod(可通过命令行覆盖:java -jar user-demo.jar --spring.profiles.active=prod)。

方式 2:单文件多环境:用 --- 分隔,适合简单场景。

2. 全局异常处理

通过 @RestControllerAdvice + @ExceptionHandler 统一处理异常:

java 复制代码
package com.example.userdemo.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

// 全局异常处理,作用于所有@RestController
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理自定义业务异常
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<String> handleBusinessException(BusinessException e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }

    // 处理通用异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return new ResponseEntity<>("服务器内部错误:" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
3. 应用监控(Actuator)

引入依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置暴露端点:

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,beans # 暴露的端点
  endpoint:
    health:
      show-details: always # 显示健康详情

访问监控端点:

健康状态:http://localhost:8080/actuator/health

应用信息:http://localhost:8080/actuator/info

Bean 列表:http://localhost:8080/actuator/beans

4. 打包与部署

打包为可执行 JAR:

bash 复制代码
mvn clean package # 打包后生成 target/user-demo-0.0.1-SNAPSHOT.jar

运行 JAR 包:

bash 复制代码
java -jar user-demo-0.0.1-SNAPSHOT.jar # 直接运行
# 带参数运行(覆盖配置)
java -jar user-demo-0.0.1-SNAPSHOT.jar --server.port=8081 --spring.profiles.active=prod

生产环境部署:可结合 Docker、K8s 实现容器化部署。


六、Spring Boot 与微服务

Spring Boot 是微服务架构的基础,结合 Spring Cloud 可构建完整的微服务体系:

Spring Boot:负责单个微服务的快速开发、独立部署;

Spring Cloud:基于 Spring Boot 提供微服务治理能力(服务注册发现、配置中心、熔断降级、网关等);

核心组件:Spring Cloud Netflix(Eureka、Ribbon、Hystrix)、Spring Cloud Alibaba(Nacos、Sentinel)、Spring Cloud Gateway 等。


七、Spring 与Spring Boot的区别

维度 Spring 框架 Spring Boot
定位 一站式企业级 Java 开发框架(核心是 IoC/DI、AOP) Spring 框架的快速开发脚手架(简化配置、快速启动)
配置方式 大量手动配置(XML 为主,后期支持注解) 自动配置(Auto-configuration)+ 少量手动配置
依赖管理 手动引入所有依赖,需手动解决版本冲突 起步依赖(Starter),一键引入相关依赖,自动管理版本
内嵌服务器 无,需手动部署到 Tomcat/Jetty 等 内置 Tomcat/Jetty/Undertow,直接运行 JAR 包
启动方式 需部署到外部服务器,或编写复杂启动类 直接运行 main 方法,或 java -jar 启动
开发效率 低(配置繁琐、依赖易冲突) 高(零配置 / 少配置,快速搭建项目)
适用场景 复杂定制化项目(需深度控制配置) 快速开发微服务、RESTful API、中小型应用

八、配置文件

Spring Boot 默认支持 application.properties/application.yml,是项目内的静态配置(如数据库地址、端口)

Spring Boot 默认加载 src/main/resources 下的 application.propertiesapplication.yml,推荐用 application.yml(语法更简洁)。

示例配置文件(application.yml)

yaml 复制代码
# 自定义普通配置
app:
  name: "我的SpringBoot应用"
  version: "1.0.0"
  author: "张三"
# 嵌套配置
database:
  mysql:
    url: "jdbc:mysql://localhost:3306/test"
    username: "root"
    password: "123456"
# 数组/列表配置
servers:
  - "192.168.1.100"
  - "192.168.1.101"
  - "192.168.1.102"
读取配置的 3 种常用方法
方法 1:@Value 注解(简单配置,直接读取)

适合读取单个、简单的配置项,直接注入到变量中。

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController {

    // 读取普通字符串配置
    @Value("${app.name}")
    private String appName;

    @Value("${app.version}")
    private String appVersion;

    // 读取嵌套配置
    @Value("${database.mysql.url}")
    private String mysqlUrl;

    // 读取列表配置(需用#{}解析)
    @Value("${servers}")
    private List<String> serverList;

    // 配置不存在时设置默认值(避免报错)
    @Value("${app.port:8080}") // 若app.port未配置,默认值8080
    private Integer appPort;

    @GetMapping("/config/value")
    public String getConfigByValue() {
        return String.format(
            "应用名称:%s,版本:%s,MySQL地址:%s,默认端口:%d,服务器列表:%s",
            appName, appVersion, mysqlUrl, appPort, serverList.toString()
        );
    }
}
方法 2:@ConfigurationProperties 注解(批量绑定,推荐复杂配置)

适合读取一组相关的配置(如数据库配置、自定义应用配置),批量绑定到一个实体类,更优雅、易维护。

步骤 1:创建配置实体类

java 复制代码
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;

// 声明这是配置属性类,prefix指定配置前缀
@ConfigurationProperties(prefix = "app")
// 注册为Spring组件,才能被注入使用
@Component
public class AppConfig {
    // 字段名需与配置文件中的key一致(如app.name → name)
    private String name;
    private String version;
    private String author;
    // 嵌套配置(对应database.mysql)
    private DatabaseConfig database;
    // 列表配置
    private List<String> servers;

    // 静态内部类:绑定嵌套的database.mysql配置
    public static class DatabaseConfig {
        private String url;
        private String username;
        private String password;

        // 生成getter/setter(必须!否则无法绑定)
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }

    // 生成所有字段的getter/setter(IDEA可快捷键:Alt+Insert → Getter and Setter)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
    public DatabaseConfig getDatabase() { return database; }
    public void setDatabase(DatabaseConfig database) { this.database = database; }
    public List<String> getServers() { return servers; }
    public void setServers(List<String> servers) { this.servers = servers; }
}

步骤 2:注入并使用配置类

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController2 {

    // 注入配置实体类
    @Autowired
    private AppConfig appConfig;

    @GetMapping("/config/batch")
    public String getConfigByBatch() {
        return String.format(
            "应用信息:%s(v%s),作者:%s;MySQL地址:%s,用户名:%s;服务器列表:%s",
            appConfig.getName(),
            appConfig.getVersion(),
            appConfig.getAuthor(),
            appConfig.getDatabase().getUrl(),
            appConfig.getDatabase().getUsername(),
            appConfig.getServers().toString()
        );
    }
}
方法 3:注入 Environment 接口(通用方式)

Environment 是 Spring 核心接口,可读取所有配置(包括配置文件、环境变量、命令行参数),适合动态读取配置。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController3 {

    // 注入Environment
    @Autowired
    private Environment env;

    @GetMapping("/config/env")
    public String getConfigByEnv() {
        // 通过key读取配置
        String appName = env.getProperty("app.name");
        String mysqlPwd = env.getProperty("database.mysql.password");
        // 读取时指定默认值
        String appDesc = env.getProperty("app.desc", "这是一个默认描述");

        return String.format(
            "应用名称:%s,MySQL密码:%s,应用描述:%s",
            appName, mysqlPwd, appDesc
        );
    }
}

Spring Boot 读取配置的优先级从高到低:

  1. 命令行参数(--key=value
  2. 操作系统环境变量
  3. application.yml/application.properties(项目内)
  4. 内置默认配置
properties 与 YAML 对比表
维度 properties 格式 YAML 格式
语法结构 键值对格式:key=value,层级用 . 分隔 层级缩进格式:key: value,依赖空格缩进(不能用 Tab)
数据类型支持 仅支持字符串(需手动转换类型) 原生支持字符串、数字、布尔、列表、对象等
层级表达 重复前缀(如 database.mysql.url 缩进嵌套,无重复前缀,更简洁
列表 / 数组支持 需特殊格式(如 servers[0]=192.168.1.1 原生支持 - 符号定义列表,直观易懂
注释 仅支持单行注释(# 仅支持单行注释(#
多环境配置 需拆分文件(如 application-dev.properties 可单文件通过 --- 分隔多环境,也可拆分文件
兼容性 所有 Java 框架都支持,无兼容问题 需依赖 SnakeYAML 库(Spring Boot 已内置),低版本框架可能不支持
可读性 简单配置清晰,复杂配置冗余 复杂配置结构清晰,简洁易读
语法差异:
properties:键值对 + 点分隔层级

语法是 层级1.层级2.键=值,所有值默认是字符串,即使写数字 / 布尔,读取时也需手动转换。

properties 复制代码
# application.properties 示例
# 基础键值对
app.name=我的SpringBoot应用
app.version=1.0.0
app.enabled=true  # 本质是字符串"true",不是布尔值

# 层级嵌套(重复前缀)
database.mysql.url=jdbc:mysql://localhost:3306/test
database.mysql.username=root
database.mysql.password=123456

# 列表/数组(语法繁琐)
servers[0]=192.168.1.100
servers[1]=192.168.1.101
servers[2]=192.168.1.102
YAML:缩进 + 冒号分隔,支持复杂结构

语法是 层级1: 换行 + 缩进 + 层级2: 值必须用空格缩进(2 个空格最佳,不能用 Tab),原生支持多数据类型和嵌套结构。

yaml 复制代码
# application.yml 示例
# 基础键值对(注意冒号后有空格)
app:
  name: 我的SpringBoot应用
  version: 1.0.0  # 数字类型
  enabled: true    # 布尔类型(原生支持)

# 层级嵌套(无重复前缀,缩进体现层级)
database:
  mysql:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456

# 列表/数组(- 符号定义,直观)
servers:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102

# 更复杂的对象列表(YAML 优势)
users:
  - name: 张三
    age: 25
    enabled: true
  - name: 李四
    age: 30
    enabled: false
数据类型支持差异:

properties :所有配置值都是字符串,比如你写 app.port=8080,读取到的是字符串 "8080",若要转成整数,需手动处理:

java 复制代码
@Value("${app.port}")
private String portStr; // 读出来是字符串

// 手动转整数
int port = Integer.parseInt(portStr);

YAML:原生支持多类型,Spring Boot 会自动转换类型:

java 复制代码
@Value("${app.port}")
private int port; // 直接读成整数,无需转换

@Value("${app.enabled}")
private boolean enabled; // 直接读成布尔值
多环境配置差异:

Spring Boot 支持多环境(开发 / 测试 / 生产)配置,两者实现方式不同:

properties 实现多环境

需拆分多个文件,比如:

application-dev.properties(开发环境)

application-test.properties(测试环境)

application-prod.properties(生产环境)

然后在主配置文件 application.properties 中指定激活的环境:

properties 复制代码
spring.profiles.active=dev # 激活开发环境
YAML 实现多环境

两种方式:

方式 1:拆分文件(和 properties 一样,如 application-dev.yml);

方式 2:单文件分隔(更简洁,用 --- 分隔不同环境):

yaml 复制代码
# 全局配置(所有环境共用)
server:
  port: 8080

# 开发环境(dev)
---
spring:
  profiles: dev
database:
  mysql:
    url: jdbc:mysql://localhost:3306/dev_db

# 生产环境(prod)
---
spring:
  profiles: prod
database:
  mysql:
    url: jdbc:mysql://prod-server:3306/prod_db

激活环境:spring.profiles.active=prod

九、常用注解

1.@SpringBootApplication

作用:Spring Boot 项目的启动核心注解,是组合注解(包含 @Configuration@EnableAutoConfiguration@ComponentScan),放在项目启动类上,触发自动配置、组件扫描等核心逻辑。

示例:

java 复制代码
// 项目入口类,放在根包下
@SpringBootApplication
// 可选:排除不需要的自动配置类
// @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
    public static void main(String[] args) {
        // 启动 Spring Boot 应用
        SpringApplication.run(DemoApplication.class, args);
    }
}
2. @Configuration

作用:标记类为配置类,替代传统 Spring 的 XML 配置文件,可在类中通过 @Bean 注解手动注册组件到 Spring 容器。

示例:

java 复制代码
// 自定义配置类
@Configuration
public class MyAppConfig {
    // 注册 RestTemplate 组件,供其他类注入使用
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    // 注册 RedisTemplate 组件(示例)
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        return template;
    }
}
3. @ComponentScan

作用:指定 Spring 扫描组件的包路径,默认扫描当前注解所在类的包及子包;若启动类和业务类不在同一包层级,需手动指定扫描路径。

示例:

java 复制代码
// 手动指定扫描多个包
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.controller", "com.example.service"})
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
4. @EnableAutoConfiguration

作用:开启 Spring Boot 自动配置核心逻辑,已包含在 @SpringBootApplication 中,一般不单独使用;底层通过扫描自动配置类,根据依赖和条件自动初始化组件。

示例:

java 复制代码
// 极少单独使用,通常结合 @Configuration 使用
@Configuration
@EnableAutoConfiguration
public class CustomAutoConfig {}
组件注册注解

用于将类标记为 Spring 容器管理的 Bean,实现依赖注入,是分层开发的核心注解。

1. @Component

作用:通用组件注解,标记任意类为 Spring Bean,是 @Controller@Service@Repository 的父注解,适用于无法归类到具体分层的通用工具类。

示例:

java 复制代码
// 通用工具类,注册为 Spring Bean
@Component
public class DateUtil {
    public String formatDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
}
2. @Controller

作用:标记类为 MVC 控制器,主要用于返回视图 / 页面(如 Thymeleaf 模板),配合 @RequestMapping 处理前端页面请求。

示例:

java 复制代码
// 页面控制器,返回 HTML 页面
@Controller
@RequestMapping("/pages")
public class PageController {
    // 访问 /pages/index 时,返回 templates/index.html 页面
    @GetMapping("/index")
    public String index(Model model) {
        model.addAttribute("title", "首页");
        return "index"; // 对应 resources/templates/index.html
    }
}
3. @RestController

作用:组合注解(@Controller + @ResponseBody),专门用于开发 RESTful API,返回 JSON / 字符串数据,而非页面,是后端接口开发的核心注解。

示例:

java 复制代码
// API 控制器,返回 JSON 数据
@RestController
@RequestMapping("/api/users")
public class UserApiController {
    // 访问 /api/users 时,返回用户列表 JSON
    @GetMapping
    public List<User> listUsers() {
        List<User> users = new ArrayList<>();
        users.add(new User(1L, "zhangsan", "123456"));
        return users;
    }
}
4. @Service

作用:标记类为业务逻辑层组件,明确标注业务层代码,便于代码分层管理和 Spring 容器识别。

示例:

java 复制代码
// 业务逻辑层,处理用户相关业务
@Service
public class UserService {
    public User getUserById(Long id) {
        // 模拟从数据库查询用户
        return new User(id, "zhangsan", "123456");
    }
    
    public void saveUser(User user) {
        // 模拟保存用户逻辑
        System.out.println("保存用户:" + user.getUsername());
    }
}
5. @Repository

作用:标记类为数据访问层(DAO/Mapper)组件,专门用于数据库操作,Spring 会自动处理数据访问相关的异常转换。

示例:

java 复制代码
// 数据访问层,操作用户表
@Repository
public class UserMapper {
    // 模拟从数据库查询用户
    public User selectById(Long id) {
        return new User(id, "zhangsan", "123456");
    }
}
6. @Autowired

作用:自动注入 Spring 容器中的 Bean(按类型注入),无需手动创建对象,是依赖注入的核心注解;可用于字段、构造方法、setter 方法。

示例:

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserApiController {
    // 字段注入:自动注入 UserService Bean
    @Autowired
    private UserService userService;
    
    // 构造方法注入(推荐,更符合依赖注入规范)
    // private final UserService userService;
    // @Autowired
    // public UserApiController(UserService userService) {
    //     this.userService = userService;
    // }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // 使用注入的 UserService 调用业务方法
        return userService.getUserById(id);
    }
}
7. @Resource

作用:JDK 原生注解,与 @Autowired 类似,用于依赖注入,但默认按名称 注入(而非类型),可通过 name 属性指定注入的 Bean 名称。

示例:

java 复制代码
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    // 按名称注入:注入名称为 "orderService" 的 Bean
    @Resource(name = "orderService")
    private OrderService orderService;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        return orderService.getOrderById(id);
    }
}
请求映射注解(高频)

用于映射 HTTP 请求(URL、请求方式),是接口开发的核心注解。

1. @RequestMapping

作用:通用请求映射注解,可映射任意 HTTP 请求方式(GET/POST/PUT/DELETE 等),可用于类(指定基础路径)或方法(指定具体路径)。

示例:

java 复制代码
@RestController
// 类级别:所有方法的基础路径为 /api/products
@RequestMapping("/api/products")
public class ProductController {
    // 方法级别:映射 GET 请求到 /api/products
    @RequestMapping(method = RequestMethod.GET)
    public List<Product> listProducts() {
        List<Product> products = new ArrayList<>();
        products.add(new Product(1L, "手机", 2999.0));
        return products;
    }
    
    // 方法级别:映射 POST 请求到 /api/products
    @RequestMapping(method = RequestMethod.POST)
    public String addProduct(@RequestBody Product product) {
        System.out.println("添加商品:" + product.getName());
        return "添加成功";
    }
}
2. @GetMapping

作用:简化版 @RequestMapping,专门映射 GET 请求,是查询类接口的常用注解。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 映射 GET 请求到 /api/products/{id}
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return new Product(id, "手机", 2999.0);
    }
}
3. @PostMapping

作用:简化版 @RequestMapping,专门映射 POST 请求,用于新增数据的接口。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 映射 POST 请求到 /api/products
    @PostMapping
    public String addProduct(@RequestBody Product product) {
        System.out.println("新增商品:" + product.getName());
        return "新增成功,商品ID:" + product.getId();
    }
}
4. @PutMapping

作用:专门映射 PUT 请求,用于更新数据的接口(全量更新)。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 映射 PUT 请求到 /api/products/{id}
    @PutMapping("/{id}")
    public String updateProduct(@PathVariable Long id, @RequestBody Product product) {
        product.setId(id);
        System.out.println("更新商品:" + product);
        return "更新成功";
    }
}
5. @DeleteMapping

作用:专门映射 DELETE 请求,用于删除数据的接口。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 映射 DELETE 请求到 /api/products/{id}
    @DeleteMapping("/{id}")
    public String deleteProduct(@PathVariable Long id) {
        System.out.println("删除商品:" + id);
        return "删除成功";
    }
}
请求参数注解

用于获取前端传递的请求参数,是接口接收参数的核心注解。

1. @PathVariable

作用:获取 URL 路径中的参数(如 /api/products/{id} 中的 id),适用于 RESTful 风格的路径参数。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 获取路径中的 id 参数
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return new Product(id, "手机", 2999.0);
    }
    
    // 多个路径参数
    @GetMapping("/{id}/category/{cid}")
    public Product getProductByCategory(@PathVariable Long id, @PathVariable Long cid) {
        return new Product(id, "手机", 2999.0);
    }
}
2. @RequestParam

作用:获取 URL 中的查询参数(如 /api/products?name=手机 中的 name),可指定参数名、是否必传、默认值。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 获取查询参数 name,非必传,默认值为空字符串
    @GetMapping("/search")
    public List<Product> searchProducts(
            @RequestParam(value = "name", required = false, defaultValue = "") String name,
            @RequestParam(value = "page", defaultValue = "1") Integer page) {
        System.out.println("搜索关键词:" + name + ",页码:" + page);
        List<Product> products = new ArrayList<>();
        products.add(new Product(1L, name, 2999.0));
        return products;
    }
}
3. @RequestBody

作用:获取 HTTP 请求体中的 JSON/XML 数据,转换为 Java 对象,适用于 POST/PUT 请求传递复杂参数(如新增 / 更新对象)。

示例:

java 复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // 获取请求体中的 JSON 数据,转换为 Product 对象
    @PostMapping
    public String addProduct(@RequestBody Product product) {
        System.out.println("商品名称:" + product.getName() + ",价格:" + product.getPrice());
        return "新增商品成功";
    }
}
4. @RequestHeader

作用:获取 HTTP 请求头中的参数(如 Token、Content-Type 等)。

示例:

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserController {
    // 获取请求头中的 Token 参数
    @GetMapping("/info")
    public String getUserInfo(@RequestHeader("Token") String token) {
        System.out.println("请求 Token:" + token);
        return "用户信息:张三,Token:" + token;
    }
}
配置读取注解

用于读取配置文件(application.yml/properties)中的配置项,实现配置与代码解耦。

1. @Value

作用:读取配置文件中的单个配置项,直接注入到字段 / 方法参数中,适用于简单配置。

示例:

java 复制代码
@Component
public class AppConfig {
    // 读取配置文件中的 app.name 配置项
    @Value("${app.name}")
    private String appName;
    
    // 读取配置项,指定默认值(配置不存在时使用)
    @Value("${app.port:8080}")
    private Integer appPort;
    
    public void printConfig() {
        System.out.println("应用名称:" + appName + ",端口:" + appPort);
    }
}
2. @ConfigurationProperties

作用:批量绑定配置文件中的配置项到 Java 对象,适用于复杂的、有层级的配置(如数据库配置、Redis 配置),比 @Value 更优雅。

示例:

java 复制代码
// 批量绑定配置文件中的 database.mysql 前缀的配置项
@Component
@ConfigurationProperties(prefix = "database.mysql")
public class MysqlConfig {
    private String url;
    private String username;
    private String password;
    
    // 必须提供 getter/setter 方法
    public String getUrl() {
        return url;
    }
    
    public void setUrl(String url) {
        this.url = url;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public void printConfig() {
        System.out.println("MySQL URL:" + url + ",用户名:" + username);
    }
}
事务管理注解

用于控制数据库事务,保证数据操作的原子性。

@Transactional

作用:标记方法 / 类为事务性操作,当方法执行过程中抛出异常时,自动回滚数据库操作;可用于类(所有方法生效)或方法(仅当前方法生效)。

示例:

java 复制代码
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private OrderItemMapper orderItemMapper;
    
    // 事务注解:当方法抛出异常时,所有数据库操作回滚
    @Transactional(rollbackFor = Exception.class) // 指定所有异常都回滚(默认仅运行时异常)
    public void createOrder(Order order, List<OrderItem> items) {
        // 保存订单
        orderMapper.insert(order);
        // 保存订单项
        for (OrderItem item : items) {
            item.setOrderId(order.getId());
            orderItemMapper.insert(item);
        }
        // 模拟异常,触发事务回滚
        // int a = 1 / 0;
    }
}
异常处理注解

用于全局统一处理接口异常,避免接口返回杂乱的异常信息。

@RestControllerAdvice

作用:全局异常处理注解,结合 @ExceptionHandler 使用,专门处理 @RestController 注解的控制器异常,返回 JSON 格式的异常信息。

示例:

java 复制代码
// 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 处理自定义业务异常
    @ExceptionHandler(BusinessException.class)
    public Map<String, Object> handleBusinessException(BusinessException e) {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 400);
        result.put("message", e.getMessage());
        return result;
    }
    
    // 处理所有未捕获的异常
    @ExceptionHandler(Exception.class)
    public Map<String, Object> handleException(Exception e) {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 500);
        result.put("message", "服务器内部错误:" + e.getMessage());
        return result;
    }
}
其他常用注解
1. @ResponseBody

作用:将方法返回值转换为 JSON / 字符串,直接写入 HTTP 响应体,单独使用时可加在 @Controller 注解的方法上(等同于 @RestController)。

示例:

java 复制代码
@Controller
@RequestMapping("/api/test")
public class TestController {
    // 单独使用 @ResponseBody,返回 JSON 数据
    @GetMapping
    @ResponseBody
    public Map<String, String> test() {
        Map<String, String> result = new HashMap<>();
        result.put("msg", "success");
        return result;
    }
}
2. @CrossOrigin

作用:解决跨域问题,允许指定的域名访问当前接口,适用于前后端分离项目。

示例:

java 复制代码
// 允许所有域名跨域访问该控制器的所有接口
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController {
    @GetMapping
    public List<User> listUsers() {
        List<User> users = new ArrayList<>();
        users.add(new User(1L, "zhangsan", "123456"));
        return users;
    }
}

核心启动配置@SpringBootApplication@Configuration 是项目启动的基础,必掌握;

组件注册@RestController@Service@Repository@Autowired 是分层开发的核心,高频使用;

接口开发@GetMapping/@PostMapping@PathVariable/@RequestParam/@RequestBody 是接口接收请求的核心;

配置读取 :简单配置用 @Value,复杂配置用 @ConfigurationProperties

事务 & 异常@Transactional 保证数据一致性,@RestControllerAdvice 统一处理异常,是企业开发必备。

总结

  1. 核心本质:Spring Boot 是 Spring 框架的 "增强脚手架",核心是 "自动配置 + 起步依赖 + 内嵌服务器",解决传统 Spring 配置繁琐、依赖复杂的问题;
  2. 核心特性:约定大于配置、开箱即用、简化依赖管理、内置服务器、完善的配置体系;
  3. 开发思路:通过 Spring Initializr 快速建项目,基于注解开发业务逻辑,利用配置文件管理环境参数,最终打包为可执行 JAR 部署。

为 JSON / 字符串,直接写入 HTTP 响应体,单独使用时可加在 @Controller 注解的方法上(等同于 @RestController)。

示例:

java 复制代码
@Controller
@RequestMapping("/api/test")
public class TestController {
    // 单独使用 @ResponseBody,返回 JSON 数据
    @GetMapping
    @ResponseBody
    public Map<String, String> test() {
        Map<String, String> result = new HashMap<>();
        result.put("msg", "success");
        return result;
    }
}
2. @CrossOrigin

作用:解决跨域问题,允许指定的域名访问当前接口,适用于前后端分离项目。

示例:

java 复制代码
// 允许所有域名跨域访问该控制器的所有接口
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController {
    @GetMapping
    public List<User> listUsers() {
        List<User> users = new ArrayList<>();
        users.add(new User(1L, "zhangsan", "123456"));
        return users;
    }
}

核心启动配置@SpringBootApplication@Configuration 是项目启动的基础,必掌握;

组件注册@RestController@Service@Repository@Autowired 是分层开发的核心,高频使用;

接口开发@GetMapping/@PostMapping@PathVariable/@RequestParam/@RequestBody 是接口接收请求的核心;

配置读取 :简单配置用 @Value,复杂配置用 @ConfigurationProperties

事务 & 异常@Transactional 保证数据一致性,@RestControllerAdvice 统一处理异常,是企业开发必备。

总结

  1. 核心本质:Spring Boot 是 Spring 框架的 "增强脚手架",核心是 "自动配置 + 起步依赖 + 内嵌服务器",解决传统 Spring 配置繁琐、依赖复杂的问题;
  2. 核心特性:约定大于配置、开箱即用、简化依赖管理、内置服务器、完善的配置体系;
  3. 开发思路:通过 Spring Initializr 快速建项目,基于注解开发业务逻辑,利用配置文件管理环境参数,最终打包为可执行 JAR 部署。

Spring Boot 是当前 Java 后端开发的主流框架,掌握其核心原理和开发方式,是从事企业级 Java 开发的必备技能。

相关推荐
Flamingˢ2 小时前
Verilog中reg与wire的区别:从语法到实战
学习·fpga开发·硬件工程
零度@2 小时前
Java 消息中间件 - 云原生多租户:Pulsar 保姆级全解2026
java·开发语言·云原生
一路向北⁢2 小时前
企业级敏感词拦截检查系统设计方案(Spring Boot)
spring boot·后端·bootstrap·敏感词·敏感词拦截
野犬寒鸦2 小时前
从零起步学习RabbitMQ || 第一章:认识消息队列及项目实战中的技术选型
java·数据库·后端
IT 行者2 小时前
Spring Security OAuth2 ID Token 生成机制深度解析
服务器·spring
信奥胡老师2 小时前
P14917 [GESP202512 五级] 数字移动
开发语言·数据结构·c++·学习·算法
海鸥812 小时前
k8s中items.key的解析和实例
java·docker·kubernetes
老毛肚2 小时前
Spring源码探究1.0
java·后端·spring
深情的小陈同学2 小时前
工作学习笔记 —— 解决刷新缓存问题
笔记·学习·ai编程