Skip to content

Spring Boot

核心特性

什么是Spring Boot?

答案: Spring Boot是Spring的快速开发脚手架,简化了Spring应用的配置和部署。

核心特性

  • 自动配置:根据依赖自动配置Spring应用
  • 起步依赖:简化Maven/Gradle配置
  • 内嵌服务器:Tomcat、Jetty、Undertow
  • 生产就绪:健康检查、监控、外部化配置
  • 无代码生成:无需XML配置

Spring Boot的启动流程?

答案:

java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

启动流程

1. 创建SpringApplication对象
   - 推断应用类型(Servlet/Reactive/None)
   - 加载ApplicationContextInitializer
   - 加载ApplicationListener

2. 运行run方法
   - 创建StopWatch(计时)
   - 获取SpringApplicationRunListeners
   - 准备Environment(环境变量、配置文件)
   - 打印Banner
   - 创建ApplicationContext
   - 准备ApplicationContext
   - 刷新ApplicationContext(核心)
   - 调用Runners(CommandLineRunner、ApplicationRunner)

3. 返回ApplicationContext

@SpringBootApplication注解的作用?

答案: @SpringBootApplication是一个组合注解,包含:

java
@SpringBootConfiguration  // 等同于@Configuration
@EnableAutoConfiguration  // 开启自动配置
@ComponentScan           // 组件扫描

详细说明

  • @SpringBootConfiguration:标记为配置类
  • @EnableAutoConfiguration:自动配置核心,根据classpath中的jar包自动配置
  • @ComponentScan:扫描当前包及子包的组件

Spring Boot自动配置原理?

答案:

核心注解:@EnableAutoConfiguration

工作流程

1. @EnableAutoConfiguration

2. @Import(AutoConfigurationImportSelector.class)

3. 读取META-INF/spring.factories

4. 加载所有AutoConfiguration类

5. 根据@Conditional条件判断是否生效

6. 生效的配置类注册到容器

示例

java
// RedisAutoConfiguration
@Configuration
@ConditionalOnClass(RedisOperations.class)  // classpath中有Redis类
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 容器中没有RedisTemplate才创建
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate
    }
}

常见@Conditional注解

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

如何自定义Starter?

答案:

步骤

1. 创建Maven项目

xml
<artifactId>my-spring-boot-starter</artifactId>

2. 添加依赖

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

3. 创建配置类

java
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
    private String name;
    private int timeout;
    // getter/setter
}

@Configuration
@EnableConfigurationProperties(MyServiceProperties.class)
@ConditionalOnClass(MyService.class)
public class MyServiceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyServiceProperties properties) {
        return new MyService(properties);
    }
}

4. 创建spring.factories

properties
# src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyServiceAutoConfiguration

5. 使用Starter

xml
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
</dependency>
yaml
# application.yml
my:
  service:
    name: test
    timeout: 3000

配置管理

Spring Boot配置文件加载顺序?

答案:

优先级(从高到低)

1. 命令行参数
2. SPRING_APPLICATION_JSON
3. ServletConfig初始化参数
4. ServletContext初始化参数
5. JNDI属性
6. Java系统属性(System.getProperties())
7. 操作系统环境变量
8. RandomValuePropertySource
9. jar包外的application-{profile}.properties/yml
10. jar包内的application-{profile}.properties/yml
11. jar包外的application.properties/yml
12. jar包内的application.properties/yml
13. @PropertySource
14. 默认属性(SpringApplication.setDefaultProperties)

示例

bash
# 命令行参数优先级最高
java -jar app.jar --server.port=8081

# 环境变量
export SERVER_PORT=8082

# application.yml
server:
  port: 8080

@Value和@ConfigurationProperties的区别?

答案:

特性@Value@ConfigurationProperties
功能注入单个属性批量注入
松散绑定不支持支持
SpEL支持不支持
JSR303校验不支持支持
复杂类型不支持支持
java
// @Value
@Value("${server.port}")
private int port;

@Value("#{systemProperties['user.name']}")  // SpEL
private String userName;

// @ConfigurationProperties
@ConfigurationProperties(prefix = "server")
@Validated
public class ServerProperties {
    @Min(1024)
    @Max(65535)
    private int port;

    private List<String> hosts;
    private Map<String, String> config;
    // getter/setter
}

松散绑定

yaml
# 以下都能绑定到serverPort字段
server-port: 8080
server_port: 8080
serverPort: 8080
SERVER_PORT: 8080

多环境配置如何管理?

答案:

1. 多配置文件

application.yml          # 公共配置
application-dev.yml      # 开发环境
application-test.yml     # 测试环境
application-prod.yml     # 生产环境

2. 激活profile

yaml
# application.yml
spring:
  profiles:
    active: dev  # 激活dev环境
bash
# 命令行
java -jar app.jar --spring.profiles.active=prod

# 环境变量
export SPRING_PROFILES_ACTIVE=prod

3. 单文件多环境

yaml
spring:
  profiles:
    active: dev

---
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080

---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80

监控与管理

Spring Boot Actuator是什么?

答案: Actuator提供生产就绪的监控和管理功能。

添加依赖

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

常用端点

端点说明
/actuator/health健康检查
/actuator/info应用信息
/actuator/metrics指标信息
/actuator/env环境变量
/actuator/loggers日志配置
/actuator/threaddump线程dump
/actuator/heapdump堆dump

配置

yaml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics  # 暴露端点
  endpoint:
    health:
      show-details: always  # 显示详细健康信息

自定义健康检查

java
@Component
public class MyHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        // 检查逻辑
        boolean isHealthy = checkHealth();
        if (isHealthy) {
            return Health.up()
                .withDetail("status", "running")
                .build();
        } else {
            return Health.down()
                .withDetail("error", "service unavailable")
                .build();
        }
    }
}

练习题

  1. Spring Boot如何实现热部署?
  2. Spring Boot如何整合MyBatis?
  3. Spring Boot如何实现异步任务?
  4. Spring Boot如何实现定时任务?

Released under the MIT License.