SpringBoot 项目创建(IDEA不全,还需要修改)

1. 导学与今日内容

本篇文章基黑马程序员的 SpringBoot 视频课程整理而成,覆盖从基础入门到高级进阶的全部核心知识点。全文分为两大部分:第一部分是 SpringBoot 基础篇,包含快速入门、起步依赖原理、配置体系(yaml、profile、加载顺序)、整合 Junit、Redis、MyBatis 等内容;第二部分是 SpringBoot 高级篇,包含自动配置原理(Condition、Enable 注解、@Import、@EnableAutoConfiguration)、自定义 starter、事件监听、启动流程分析以及监控 actuator。每个章节都会给出详细的 IDEA 创建项目过程、可运行的代码示例和关键原理讲解。

建议读者按照章节顺序学习,先掌握基础用法,再深入理解自动配置的底层原理,最后通过自定义 starter 和监控实战把知识串联起来。

2. SpringBoot 概述

SpringBoot 是 Spring 家族中用于简化 Spring 应用搭建和开发的框架。它的核心设计理念是「约定优于配置」,通过自动配置和起步依赖,让开发者用最少的配置快速构建独立运行的 Spring 应用。

SpringBoot 主要解决以下痛点:

  • 配置繁琐:传统 Spring 项目需要大量 XML 或注解配置,SpringBoot 通过自动配置大幅减少手工配置。
  • 依赖管理困难:SpringBoot 提供起步依赖(Starter),把常用依赖打包,统一管理版本,避免版本冲突。
  • 部署复杂:SpringBoot 内嵌 Tomcat、Jetty 等服务器,打成可执行 jar 后一条命令即可运行,无需外部容器。

SpringBoot 的核心能力包括:自动配置(Auto Configuration)、起步依赖(Starter)、内嵌服务器、Actuator 监控、外部化配置等。

3. SpringBoot 快速入门

3.1 环境准备

开始之前需要准备以下环境:

  • JDK 8 或更高版本
  • Maven 3.6 或更高版本
  • IDEA 2020 或更高版本(社区版或旗舰版均可)

3.2 使用 IDEA 创建 SpringBoot 项目

下面给出使用 IDEA 创建 SpringBoot 项目的完整步骤:

第一步:新建项目

打开 IDEA,点击 File → New → Project,在弹出的窗口左侧选择 Spring Initializr。如果网络环境无法访问 Spring 官方脚手架,可以选择 Custom 并填写阿里云镜像地址:https://start.aliyun.com

第二步:填写项目基本信息

在 Project Metadata 区域填写:

  • Group:例如 com.example
  • Artifact:例如 springboot-quickstart
  • Type:选择 Maven Project
  • Language:Java
  • Packaging:Jar
  • Java Version:8 或 11

第三步:选择起步依赖

在 Dependencies 页面勾选需要的依赖。快速入门阶段只需要勾选 Spring Web,点击 Creat 完成创建。

第四步:等待依赖下载

IDEA 会自动下载 Maven 依赖,右下角进度条完成后项目结构就创建好了。默认会生成一个带有 @SpringBootApplication 注解的主启动类。

3.3 编写第一个接口

创建项目后,编写一个简单的 Controller 来验证环境是否正常:

java 复制代码
package com.example.springbootquickstart;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
    return "Hello SpringBoot!";
}
}

运行主启动类,控制台出现 Tomcat started on port(s): 8080 后,在浏览器访问 http://localhost:8080/hello,即可看到返回的字符串。

4. 快速构建 SpringBoot 工程

除了通过 IDEA 图形界面创建,还可以使用 Spring Initializr 网页版或 Maven 命令行快速构建工程。

4.1 使用网页版 Spring Initializr

访问 https://start.spring.io,填写项目元数据,选择依赖后点击 Generate 下载压缩包,解压后用 IDEA 以 Maven 项目方式导入即可。

4.2 使用 Maven 命令行创建

在命令行执行以下命令生成项目骨架:

bash 复制代码
mvn archetype:generate -DgroupId=com.example -DartifactId=springboot-cli -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

生成后手动在 pom.xml 中加入 SpringBoot 父工程和起步依赖:

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

然后创建主启动类和 Controller,即可运行。

5. SpringBoot 起步依赖原理分析

起步依赖(Starter)是 SpringBoot 简化依赖管理的核心机制。以 spring-boot-starter-web 为例,它本身并不包含业务代码,而是一个聚合依赖,内部通过 pom 文件统一引入了 Spring MVC、内嵌 Tomcat、Jackson 等 Web 开发所需的全部依赖,并锁定了兼容版本。

原理上,每个 starter 的 pom.xml 中通过 <dependencies> 声明了一组依赖,Maven 在解析时会自动传递引入这些依赖。这样开发者只需要引入一个 starter,就能获得一整套功能,无需关心版本号,避免版本冲突。

常见的起步依赖包括:

  • spring-boot-starter-web:Web 开发,内嵌 Tomcat,Spring MVC
  • spring-boot-starter-data-redis:Redis 整合
  • spring-boot-starter-jdbc:JDBC 数据库操作
  • spring-boot-starter-test:单元测试
  • mybatis-spring-boot-starter:MyBatis 整合(第三方提供)

6. SpringBoot 配置:配置文件分类

SpringBoot 支持多种配置文件格式,常用的有三种:

  • application.properties :传统的 properties 格式,使用 key=value 写法。
  • application.yml:YAML 格式,层级清晰,是目前推荐的方式。
  • application.yaml:与 yml 等价,SpringBoot 同样支持。

当同时存在多个配置文件时,SpringBoot 的加载优先级为:properties 高于 yml 高于 yaml。也就是说,如果同一个配置项在多个文件中都出现,properties 中的值会生效。

配置文件默认放在 src/main/resources 目录下,SpringBoot 启动时会自动加载。

7. SpringBoot 配置:yaml 基本语法

YAML(YAML Ain't Markup Language)是一种以数据为中心的标记语言,使用缩进表示层级关系。基本语法规则如下:

  • 大小写敏感
  • 使用空格缩进表示层级,不能使用 Tab
  • 缩进空格数不要求固定,但同级元素必须左对齐
  • key: value 格式,冒号后必须有空格

示例:

yaml 复制代码
server:
  port: 8080
  servlet:
    context-path: /demo

对应 properties 写法为:

properties 复制代码
server.port=8080
server.servlet.context-path=/demo

8. SpringBoot 配置:yaml 数据格式

YAML 支持多种数据类型,包括普通值、对象、数组等。

8.1 普通值(字面量)

yaml 复制代码
name: zhangsan
age: 25
married: true

8.2 对象(Map)

yaml 复制代码
person:
  name: zhangsan
  age: 25

也可以使用行内写法:

yaml 复制代码
person: {name: zhangsan, age: 25}

8.3 数组(List / Set)

yaml 复制代码
hobby:
  - 篮球
  - 足球
  - 编程

行内写法:

yaml 复制代码
hobby: [篮球, 足球, 编程]

8.4 对象数组

yaml 复制代码
users:
  - name: zhangsan
    age: 25
  - name: lisi
    age: 30

9. SpringBoot 配置:获取数据(一)

在代码中获取 yaml 配置数据有多种方式,最基础的是使用 @Value 注解。

java 复制代码
@RestController
public class ConfigController {
@Value("${server.port}")
private int port;
@Value("${person.name}")
private String name;
@GetMapping("/config")
public String getConfig() {
return "port=" + port + ", name=" + name;
}
}

@Value 注解通过 ${...} 占位符读取配置文件中的值,适合读取单个配置项。当配置项较多时,这种方式会显得繁琐,此时可以使用 @ConfigurationProperties 批量绑定。

10. SpringBoot 配置:获取数据(二)

当需要批量读取一组配置时,使用 @ConfigurationProperties 注解将配置绑定到 Java 对象。

首先在 yaml 中定义配置:

yaml 复制代码
person:
  name: zhangsan
  age: 25
  hobby:
    - 篮球
    - 编程

然后创建对应的实体类:

java 复制代码
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age;
private List&lt;String&gt; hobby;
// getter 和 setter 省略
}

使用 @ConfigurationProperties 时需要注意:

  • prefix 指定配置的前缀,对应 yaml 中的顶层 key。
  • 实体类需要提供 getter 和 setter 方法。
  • 实体类需要交给 Spring 管理,可以加 @Component 注解。

这种方式适合配置项较多、结构复杂的场景,代码更清晰,也便于类型校验。

11. SpringBoot 配置:profile

在实际开发中,不同环境(开发、测试、生产)往往需要不同的配置。SpringBoot 通过 profile 机制支持多环境配置切换。

11.1 多 profile 文件方式

创建多个配置文件,命名规则为 application-{profile}.yml

  • application-dev.yml:开发环境
  • application-test.yml:测试环境
  • application-prod.yml:生产环境

然后在主配置文件 application.yml 中指定激活哪个环境:

yaml 复制代码
spring:
  profiles:
    active: dev

11.2 单文件多文档块方式

在同一个 yaml 文件中使用 --- 分隔多个文档块,每个块通过 spring.profiles 指定环境名:

yaml 复制代码
server:
  port: 8080
spring:
  profiles:
    active: dev
---
server:
  port: 8081
spring:
  profiles: dev
---
server:
  port: 8082
spring:
  profiles: prod

11.3 命令行激活 profile

打包运行时可以通过命令行参数指定激活的环境:

bash 复制代码
java -jar app.jar --spring.profiles.active=prod

12. SpringBoot 配置:项目内部配置文件加载顺序

SpringBoot 在项目内部会按以下顺序加载配置文件,后面的配置会覆盖前面的配置:

  1. file:./config/:项目根目录下的 config 目录
  2. file:./:项目根目录
  3. classpath:/config/:classpath 下的 config 目录
  4. classpath:/:classpath 根目录

也就是说,如果把配置文件放在项目根目录的 config 文件夹下,它的优先级最高,会覆盖 classpath 下的同名配置。这个机制方便在部署时通过外部配置文件覆盖默认配置,而无需重新打包。

13. SpringBoot 配置:项目外部配置加载顺序

除了项目内部的配置文件,SpringBoot 还支持从外部加载配置,优先级从高到低依次为:

  1. 命令行参数,例如 --server.port=9090
  2. Java 系统属性,通过 -D 传入
  3. 操作系统环境变量
  4. 项目外部的 application-{profile}.yml 文件
  5. 项目外部的 application.yml 文件
  6. 项目内部的 application-{profile}.yml 文件
  7. 项目内部的 application.yml 文件

利用这个机制,可以在不修改代码、不重新打包的情况下,通过命令行参数或外部配置文件灵活调整运行参数,非常适合生产环境部署。

14. SpringBoot 整合 Junit

SpringBoot 整合 Junit 非常简单,引入测试起步依赖后即可编写单元测试。

在 pom.xml 中引入依赖(创建项目时勾选 Spring Web 后通常已包含):

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

编写测试类:

java 复制代码
package com.example.springbootquickstart;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HelloControllerTest {
@Autowired
private HelloController helloController;
@Test
void testHello() {
String result = helloController.hello();
System.out.println(result);
}
}

关键点说明:

  • @SpringBootTest 注解会启动完整的 Spring 容器,因此可以注入 Bean 进行测试。
  • 测试类放在 src/test/java 目录下,包名通常与主类一致。
  • Junit 5 使用 @Test 注解标记测试方法。

15. SpringBoot 整合 Redis

SpringBoot 整合 Redis 需要引入起步依赖并配置连接信息。

15.1 引入依赖

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

15.2 配置连接信息

yaml 复制代码
spring:
  redis:
    host: localhost
    port: 6379
    password:
    database: 0

15.3 使用 RedisTemplate 操作数据

java 复制代码
@RestController
public class RedisController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/redis/set")
public String setValue() {
stringRedisTemplate.opsForValue().set("name", "zhangsan");
return "写入成功";
}
@GetMapping("/redis/get")
public String getValue() {
return stringRedisTemplate.opsForValue().get("name");
}
}

说明:StringRedisTemplate 是 RedisTemplate 的字符串专用版本,key 和 value 都以字符串形式存储,适合简单场景。如果需要存储对象,可以使用 RedisTemplate 并配置序列化器。

16. SpringBoot 整合 MyBatis

SpringBoot 整合 MyBatis 需要引入 MyBatis 起步依赖和数据库驱动。

16.1 引入依赖

xml 复制代码
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>

16.2 配置数据源和 MyBatis

yaml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.springbootquickstart.pojo

16.3 创建实体类和 Mapper

java 复制代码
public class User {
    private Integer id;
    private String name;
    private Integer age;
    // getter 和 setter 省略
}
java 复制代码
@Mapper
public interface UserMapper {
    List<User> findAll();
}

16.4 编写 Mapper XML

resources/mapper 目录下创建 UserMapper.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootquickstart.mapper.UserMapper">
    <select id="findAll" resultType="User">
        select * from user
    </select>
</mapper>

16.5 编写 Service 和 Controller

java 复制代码
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List&lt;User&gt; findAll() {
return userMapper.findAll();
}
}
java 复制代码
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public List&lt;User&gt; findAll() {
return userService.findAll();
}
}

注意:Mapper 接口需要加 @Mapper 注解,或者在主启动类上加 @MapperScan 注解批量扫描。

17. SpringBoot 高级:今日内容

高级篇主要围绕 SpringBoot 的自动配置原理展开,包括 Condition 条件装配、切换内置 Web 服务器、Enable 注解原理、@Import 详解、@EnableAutoConfiguration 详解、自定义 starter、事件监听、启动流程分析以及 Actuator 监控。掌握这些内容,才能真正理解 SpringBoot 的底层工作机制,并具备自定义扩展的能力。

18. SpringBoot 自动配置:Condition(一)

Condition 是 Spring 4.0 引入的条件装配机制,SpringBoot 的自动配置正是基于它实现的。通过 @Conditional 系列注解,可以在满足特定条件时才创建 Bean。

常见的条件注解包括:

  • @ConditionalOnClass:classpath 中存在指定类时生效
  • @ConditionalOnMissingBean:容器中不存在指定 Bean 时生效
  • @ConditionalOnProperty:配置文件中存在指定属性时生效
  • @ConditionalOnWebApplication:当前是 Web 应用时生效

示例:根据配置决定是否创建某个 Bean。

java 复制代码
@Configuration
public class UserConfig {
@Bean
@ConditionalOnProperty(name = "user.enable", havingValue = "true")
public User user() {
    return new User();
}
}

当配置文件中 user.enable=true 时,容器中才会创建 User 这个 Bean。

19. SpringBoot 自动配置:Condition(二)

除了使用内置的条件注解,还可以自定义 Condition 实现更灵活的判断逻辑。自定义 Condition 需要实现 Condition 接口,重写 matches 方法。

java 复制代码
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    // 获取环境变量
    Environment env = context.getEnvironment();
    String osName = env.getProperty("os.name");
    return osName != null &amp;&amp; osName.contains("Windows");
}
}

使用自定义 Condition:

java 复制代码
@Configuration
public class SystemConfig {
@Bean
@Conditional(MyCondition.class)
public SystemInfo systemInfo() {
    return new SystemInfo();
}
}

这样只有在 Windows 系统下,SystemInfo 这个 Bean 才会被创建。Condition 机制让 SpringBoot 能够根据运行环境、依赖情况、配置属性等动态决定装配哪些 Bean,这是自动配置的基石。

20. SpringBoot 自动配置:切换内置 Web 服务器

SpringBoot 默认使用内嵌 Tomcat 作为 Web 服务器,但也可以切换为 Jetty 或 Undertow。切换方法是在 pom.xml 中排除 Tomcat 依赖,引入其他服务器依赖。

切换为 Jetty:

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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

切换为 Undertow 同理,把 spring-boot-starter-jetty 换成 spring-boot-starter-undertow 即可。切换后无需修改任何业务代码,SpringBoot 会自动装配对应的服务器。

21. SpringBoot 自动配置:Enable 注解原理

SpringBoot 中大量使用 @EnableXxx 形式的注解来开启某项功能,例如 @EnableScheduling@EnableAsync@EnableConfigurationProperties 等。这些注解的底层原理是通过 @Import 注解导入配置类或注册 Bean。

@EnableScheduling 为例,它的定义如下:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
public @interface EnableScheduling {
}

可以看到,@EnableScheduling 通过 @Import 导入了 SchedulingConfiguration 配置类,从而注册了定时任务相关的 Bean。这种「注解 + @Import」的组合模式,是 SpringBoot 功能开关的通用实现方式。

22. SpringBoot 自动配置:@Import 详解

@Import 注解用于向 Spring 容器中导入组件,支持三种方式:

22.1 导入普通类

java 复制代码
@Import(User.class)
@Configuration
public class AppConfig {
}

这样 User 类会被注册为容器中的一个 Bean。

22.2 导入配置类

java 复制代码
@Import(MyConfig.class)
@Configuration
public class AppConfig {
}

MyConfig 中定义的 Bean 都会被注册。

22.3 导入 ImportSelector 实现类

java 复制代码
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.example.User", "com.example.Role"};
    }
}
java 复制代码
@Import(MyImportSelector.class)
@Configuration
public class AppConfig {
}

这种方式可以批量导入多个类,@EnableAutoConfiguration 正是通过 ImportSelector 批量加载自动配置类的。

23. SpringBoot 自动配置:@EnableAutoConfiguration 详解

@EnableAutoConfiguration 是 SpringBoot 自动配置的核心注解,它定义如下:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

关键点有两个:

  • @AutoConfigurationPackage:把主启动类所在包及其子包注册到容器,作为组件扫描的基准包。
  • @Import(AutoConfigurationImportSelector.class):通过 ImportSelector 加载所有自动配置类。

AutoConfigurationImportSelector 会读取 META-INF/spring.factories 文件中 org.springframework.boot.autoconfigure.EnableAutoConfiguration 键对应的所有配置类,再结合 Condition 条件判断,最终只装配满足条件的配置类。这就是为什么引入一个 starter 后,相关功能就能自动生效的原因。

24. SpringBoot 自动配置:自定义 starter 步骤分析

自定义 starter 是 SpringBoot 进阶的重要技能,通常用于封装公共组件供多个项目复用。实现一个 starter 需要两个模块:

  • 自动配置模块 :包含自动配置类和 spring.factories 文件。
  • starter 模块:一个空的 Maven 工程,只负责引入自动配置模块的依赖。

实现步骤概括如下:

  1. 创建自动配置模块,编写配置类和业务类。
  2. resources/META-INF 下创建 spring.factories 文件,声明自动配置类。
  3. 创建 starter 模块,在 pom.xml 中引入自动配置模块。
  4. 在其他项目中引入 starter 依赖,即可自动装配功能。

25. SpringBoot 自动配置:自定义 starter 实现(一)

下面通过一个完整的例子演示如何实现自定义 starter。假设我们要封装一个「IP 地址解析」的公共组件。

第一步:创建自动配置模块

新建 Maven 工程 ip-spring-boot-autoconfigure,编写业务类:

java 复制代码
public class IpUtils {
private String defaultIp;
public IpUtils(String defaultIp) {
this.defaultIp = defaultIp;
}
public String getIp() {
return defaultIp;
}
}

编写属性绑定类:

java 复制代码
@ConfigurationProperties(prefix = "ip")
public class IpProperties {
    private String defaultIp = "127.0.0.1";
    // getter 和 setter 省略
}

编写自动配置类:

java 复制代码
@Configuration
@EnableConfigurationProperties(IpProperties.class)
@ConditionalOnClass(IpUtils.class)
public class IpAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public IpUtils ipUtils(IpProperties properties) {
    return new IpUtils(properties.getDefaultIp());
}
}

第二步:创建 spring.factories 文件

src/main/resources/META-INF 目录下创建 spring.factories

properties 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.ip.autoconfigure.IpAutoConfiguration

26. SpringBoot 自动配置:自定义 starter 实现(二)

第三步:创建 starter 模块

新建 Maven 工程 ip-spring-boot-starter,pom.xml 中引入自动配置模块:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>ip-spring-boot-autoconfigure</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

第四步:在其他项目中使用

在业务项目的 pom.xml 中引入 starter 依赖:

xml 复制代码
<dependency>
    <groupId>com.example</groupId>
    <artifactId>ip-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

然后在 application.yml 中配置属性:

yaml 复制代码
ip:
  default-ip: 192.168.1.100

最后在业务代码中注入使用:

java 复制代码
@RestController
public class IpController {
@Autowired
private IpUtils ipUtils;
@GetMapping("/ip")
public String getIp() {
return ipUtils.getIp();
}
}

启动项目后访问 /ip 接口,即可返回配置的 IP 地址。这样就把公共能力封装成了可复用的 starter。

27. SpringBoot 事件监听

SpringBoot 在启动过程中会发布一系列事件,开发者可以通过监听这些事件在特定时机执行自定义逻辑。常用的事件包括:

  • ApplicationStartingEvent:应用启动时触发,此时环境尚未准备好。
  • ApplicationEnvironmentPreparedEvent:环境准备完成后触发。
  • ApplicationPreparedEvent:容器准备完成后触发。
  • ApplicationStartedEvent:应用启动完成、容器刷新后触发。
  • ApplicationReadyEvent:应用就绪,可以接收请求时触发。
  • ApplicationFailedEvent:启动失败时触发。

实现监听器有两种方式。方式一:实现 ApplicationListener 接口。

java 复制代码
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
    System.out.println("应用已就绪,可以接收请求了");
}
}

方式二:使用 @EventListener 注解。

java 复制代码
@Component
public class MyEventListener {
@EventListener
public void onReady(ApplicationReadyEvent event) {
    System.out.println("应用已就绪(注解方式)");
}
}

事件监听常用于启动后初始化数据、预热缓存、发送通知等场景。

28. SpringBoot 流程分析:初始化

SpringBoot 的启动入口是主启动类中的 SpringApplication.run() 方法。在 run 方法执行前,会先创建 SpringApplication 对象,初始化阶段主要做以下事情:

  • 推断应用类型:根据 classpath 判断是 Web 应用(Servlet 或 Reactive)还是普通应用。
  • 加载 spring.factories 中的 ApplicationContextInitializer 初始化器。
  • 加载 spring.factories 中的 ApplicationListener 监听器。
  • 推断主启动类:通过堆栈信息找到包含 main 方法的类。

这些初始化工作为后续的容器创建和自动配置做好了准备。

29. SpringBoot 流程分析:run 方法

SpringApplication.run() 方法是整个启动流程的核心,主要步骤包括:

  1. 创建并启动计时器,记录启动耗时。
  2. 发布 ApplicationStartingEvent 启动事件。
  3. 准备环境(Environment),加载配置文件,发布 ApplicationEnvironmentPreparedEvent
  4. 创建 ApplicationContext 容器(根据应用类型创建对应的容器实现)。
  5. 容器刷新前准备,注册 BeanNameGenerator 等。
  6. 发布 ApplicationPreparedEvent
  7. 执行 refreshContext() 刷新容器,这是 Spring 容器的核心流程,包括 Bean 的创建、自动配置的加载等。
  8. 容器刷新后处理,发布 ApplicationStartedEvent
  9. 调用 runners(ApplicationRunner 和 CommandLineRunner)。
  10. 发布 ApplicationReadyEvent,启动完成。

理解这个流程,有助于在遇到启动问题时快速定位是哪个环节出了差错。

30. SpringBoot 监控:actuator 基本使用

Actuator 是 SpringBoot 提供的生产级监控组件,可以查看应用的运行状态、健康信息、指标、日志等。

30.1 引入依赖

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

30.2 配置暴露端点

默认情况下,Actuator 只暴露 health 端点。可以通过配置暴露更多端点:

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: "*"

配置后访问 http://localhost:8080/actuator 可以看到所有可用端点。

30.3 常用端点

  • /actuator/health:健康检查,返回 UP 或 DOWN。
  • /actuator/info:应用信息。
  • /actuator/beans:查看容器中所有 Bean。
  • /actuator/env:查看环境配置。
  • /actuator/metrics:查看指标信息。
  • /actuator/mappings:查看所有 URL 映射。

Actuator 是生产环境运维的重要工具,配合监控平台可以实时掌握应用的健康状况和运行指标。

31. 总结

本文从 SpringBoot 基础入门到高级进阶,系统梳理了完整的学习路径。基础篇重点掌握 IDEA 创建项目、起步依赖、yaml 配置、profile 多环境、整合 Junit/Redis/MyBatis 等实战技能;高级篇深入理解自动配置原理(Condition、@Import、@EnableAutoConfiguration)、自定义 starter、事件监听、启动流程和 Actuator 监控。

建议学习顺序:先跟着快速入门章节在 IDEA 中亲手创建并运行一个项目,再逐步学习配置体系和整合技术,最后深入源码理解自动配置原理,并通过自定义 starter 把知识转化为实际能力。SpringBoot 的核心思想是「约定优于配置」,理解了这个思想,就能举一反三,快速掌握 SpringCloud 等更上层的框架。

相关推荐
Dr.kangder1 小时前
嵌入式面试总结(二十二)——指针
java·面试·职场和发展·架构·嵌入式
MacroZheng1 小时前
几行代码给项目集成AI功能,Spring AI 2.0太香了!
java·人工智能·spring boot
元界metalite2 小时前
SpringBoot修改接口全字段更新为什么危险-MetaLite如何只更新变化字段
spring boot
Devin~Y2 小时前
从内容社区到AI智能客服:Spring Boot + Spring Cloud + Spring AI 全栈实战面试拆解
java·spring boot·redis·elasticsearch·spring cloud·kafka·mybatis
未秃头的程序猿2 小时前
从写CRUD到做AI Agent:我花了6个月转型,这是我的完整路线图
java·后端·ai编程
Java内核笔记2 小时前
万字长文剖析 Spring Boot 4.1.0 启动流程源码:从 main 到就绪
java·后端
2602_959960922 小时前
电商大厂Java面试:从Spring Boot、JPA、微服务到Redis、Kafka、Spring Security与监控,谢飞机的爆笑三轮问答
java·jvm·spring boot·redis·面试题
码农进化录2 小时前
Java 程序员的 AI 进化论 | Spring Boot 搭企业智能客服,从设计到上线
java·spring boot·openai
旺仔学长 哈哈2 小时前
别只做车辆 CRUD:Spring Boot 共享汽车管理系统从预约到还车的完整实现---源码53766
java·spring boot·在线预约·共享汽车