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 开发的必备技能。

相关推荐
考虑考虑5 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯6 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路10 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
Java陈序员12 小时前
企业级!一个基于 Java 开发的开源 AI 应用开发平台!
spring boot·agent·mcp
像我这样帅的人丶你还13 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev15 小时前
GreenDAO → Room
android·java·kotlin
杨运交19 小时前
[041][公共模块]分布式唯一ID生成器设计与实现:一款灵活可扩展的雪花算法框架
spring boot
亦暖筑序20 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
敲代码的彭于晏20 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev21 小时前
ButterKnife → ViewBinding
android·java·kotlin