Skip to content

本轮 SpringBoot2核心功能面试题库(带答案) ​

生成时间:2026-05-24 21:07 ​


【面试题】1. @SpringBootApplication注解的三大核心注解是什么?它们的职责分别是什么? ​

【标准答案】 @SpringBootApplication是一个组合注解,包含三个核心注解:

1. @SpringBootConfiguration

  • 本质就是@Configuration,标记这是一个配置类
  • 允许在类中定义@Bean方法

2. @EnableAutoConfiguration

  • 核心注解,开启自动配置
  • 通过@Import导入AutoConfigurationImportSelector
  • 扫描META-INF/spring.factories或AutoConfiguration.imports文件,加载所有自动配置类
  • 根据条件注解@ConditionalXxx判断是否生效

3. @ComponentScan

  • 开启组件扫描,默认扫描主类所在包及其子包
  • 扫描@Controller、@Service、@Repository、@Component等注解的Bean

面试回答技巧:先说三个注解名字,再分别解释职责,最后强调@EnableAutoConfiguration是自动配置的入口。可以补充:exclude属性可以排除特定自动配置。


【面试题】2. SpringBoot的自动配置原理是什么?请详细说明加载流程。 ​

【标准答案】 自动配置原理分为四个步骤:

第一步:启动类入口

  • @EnableAutoConfiguration通过@Import导入AutoConfigurationImportSelector

第二步:加载候选配置类

  • AutoConfigurationImportSelector读取META-INF/spring.factories(旧版)或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(2.7+)
  • 获取所有EnableAutoConfiguration对应的配置类全限定名

第三步:条件过滤

  • 每个配置类上有@Conditional系列注解:
    • @ConditionalOnClass:类路径存在某类才生效
    • @ConditionalOnMissingBean:容器不存在某Bean才生效
    • @ConditionalOnProperty:配置属性满足条件才生效
  • 只有满足条件的配置类才会注册Bean

第四步:按需装配

  • 如DispatcherServletAutoConfiguration,只在Web环境下生效
  • 如DataSourceAutoConfiguration,只在有DataSource类且配置了数据源时生效

面试回答技巧:按"入口→加载→过滤→装配"四步走,强调条件注解是核心,SpringBoot不是一股脑全加载,而是按需装配。


【面试题】3. application.yml和application.properties加载顺序是怎样的?优先级如何? ​

【标准答案】 加载顺序(从高到低优先级):

  1. 命令行参数:--server.port=8081
  2. Java系统属性:-Dserver.port=8081
  3. 操作系统的环境变量:SERVER_PORT=8081
  4. jar包外部的application-{profile}.yml/properties
  5. jar包内部的application-{profile}.yml/properties
  6. jar包外部的application.yml/properties
  7. jar包内部的application.yml/properties
  8. @ConfigurationProperties注解类的默认值

关键规则:

  • 外部配置覆盖内部配置
  • 高优先级覆盖低优先级
  • yml和properties同时存在,properties优先级更高(但推荐统一用yml)
  • 相同属性会覆盖,不同属性会互补

面试回答技巧:核心记忆"命令行>外部>内部",实际开发中常用命令行参数或外部配置文件实现动态配置。


【面试题】4. @ConfigurationProperties和@Value注解有什么区别?各自的适用场景是什么? ​

【标准答案】

特性@ConfigurationProperties@Value
功能批量绑定配置到Bean单个属性注入
松散绑定支持(user-name可映射userName)不支持
SpEL表达式不支持支持
JSR303校验支持@Validated不支持
复杂对象支持Map、List、嵌套对象不支持

@ConfigurationProperties适用场景:

  • 配置项较多,需要统一管理
  • 需要校验配置合法性
  • 需要嵌套对象或集合
  • 示例:数据库连接池配置、Redis配置

@Value适用场景:

  • 只需注入个别属性
  • 需要SpEL表达式计算
  • 示例:@Value("${app.version}") private String version;

面试回答技巧:表格对比一目了然,强调@ConfigurationProperties更适合配置类,@Value更灵活轻量。可补充:@ConfigurationProperties需要配合@EnableConfigurationProperties或@Component使用。


【面试题】5. Bean的完整生命周期是怎样的?各个阶段的回调方法有哪些? ​

【标准答案】 Bean生命周期分为四个阶段:

阶段一:实例化(Instantiation)

  • BeanDefinition转换为Bean对象
  • 调用构造器创建实例
  • 扩展点:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

阶段二:属性赋值(Populate)

  • 依赖注入,设置属性值
  • 扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  • Aware接口回调:BeanNameAware、BeanFactoryAware、ApplicationContextAware

阶段三:初始化(Initialization)

  1. BeanPostProcessor.postProcessBeforeInitialization()
  2. @PostConstruct注解方法
  3. InitializingBean.afterPropertiesSet()
  4. 自定义init-method
  5. BeanPostProcessor.postProcessAfterInitialization()

阶段四:销毁(Destruction)

  1. @PreDestroy注解方法
  2. DisposableBean.destroy()
  3. 自定义destroy-method

面试回答技巧:用口诀记忆"实例化→属性赋值→初始化→销毁",重点记住三个阶段的核心回调:@PostConstruct/InitializingBean、@PreDestroy/DisposableBean。可以强调BeanPostProcessor是AOP的关键。


【面试题】6. Spring AOP的代理方式有哪两种?什么情况下用JDK动态代理,什么情况下用CGLIB? ​

【标准答案】 两种代理方式:

1. JDK动态代理

  • 基于接口实现
  • 要求目标类实现接口
  • 使用java.lang.reflect.Proxy生成代理对象
  • SpringBoot 2.x默认策略(proxy-target-class=false)

2. CGLIB代理

  • 基于继承实现
  • 通过生成目标类的子类
  • 不能代理final类和final方法
  • SpringBoot中proxy-target-class=true时使用

使用规则:

  • 目标类实现了接口:默认JDK动态代理
  • 目标类没有实现接口:必须用CGLIB
  • 强制使用CGLIB:@EnableAspectJAutoProxy(proxyTargetClass=true)

SpringBoot 2.x的变化:

  • 默认proxy-target-class=true,优先CGLIB
  • 统一代理方式,避免混淆

面试回答技巧:先说两种代理区别,再强调SpringBoot 2.x默认CGLIB,可以追问"为什么默认改了?答案是统一行为、避免代理对象类型不一致问题"。


【面试题】7. @Transactional注解的传播行为有哪些?最常用的几个是什么? ​

【标准答案】 七种传播行为:

传播行为说明使用场景
REQUIRED(默认)有事务则加入,无则新建最常用,90%场景
REQUIRES_NEW总是新建事务,挂起当前独立日志、审计记录
SUPPORTS有事务则加入,无则非事务执行查询方法
NOT_SUPPORTED非事务执行,挂起当前事务性能优化场景
MANDATORY必须在事务中调用,否则抛异常强校验场景
NEVER必须非事务调用,否则抛异常强校验场景
NESTED嵌套事务,支持部分回滚复杂业务分步处理

最常用的三个:

  1. REQUIRED:默认值,保证方法在事务中执行
  2. REQUIRES_NEW:独立事务,不受外层事务影响
  3. NESTED:嵌套事务,内层可单独回滚

面试回答技巧:重点说REQUIRED和REQUIRES_NEW的区别,举例:REQUIRES_NEW常用于日志记录,即使业务回滚,日志也要保存。


【面试题】8. SpringBoot如何实现多数据源配置?事务如何管理? ​

【标准答案】 多数据源配置步骤:

第一步:配置数据源

yaml
spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/db1
      username: root
      password: root
    secondary:
      url: jdbc:mysql://localhost:3306/db2
      username: root
      password: root

第二步:配置DataSource Bean

java
@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.primary")
    public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); }
    
    @Bean
    @ConfigurationProperties(prefix="spring.datasource.secondary")
    public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); }
}

第三步:配置事务管理器

java
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager(DataSource primaryDataSource) {
    return new DataSourceTransactionManager(primaryDataSource);
}

事务管理关键:

  • 每个数据源配置独立的事务管理器
  • 使用@Transactional(value="primaryTransactionManager")指定
  • 跨数据源事务需要分布式事务(JTA/Seata)

面试回答技巧:强调"一个数据源配一个事务管理器",可以追问"跨数据源事务怎么办?答案是分布式事务框架"。


【面试题】9. SpringBoot的Actuator提供了哪些核心端点?如何自定义健康检查? ​

【标准答案】 核心端点:

端点功能敏感信息
/health应用健康状态可能暴露数据库连接状态
/info应用信息无
/metrics性能指标无
/env环境变量可能暴露配置
/beansBean列表无
/mappingsURL映射无
/threaddump线程快照无

自定义健康检查:

java
@Component
public class CustomHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        // 自定义检查逻辑
        boolean healthy = checkExternalService();
        if (healthy) {
            return Health.up()
                .withDetail("service", "external-service")
                .withDetail("status", "available")
                .build();
        }
        return Health.down()
            .withDetail("service", "external-service")
            .withDetail("status", "unavailable")
            .build();
    }
}

安全暴露配置:

yaml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: when-authorized

面试回答技巧:强调生产环境要控制端点暴露,show-details设为when-authorized或never,避免敏感信息泄露。


【面试题】10. SpringBoot打包后的jar包结构是怎样的?如何实现分层打包优化Docker镜像? ​

【标准答案】 SpringBoot JAR包结构:

app.jar
├── BOOT-INF/
│   ├── classes/          # 应用类文件
│   └── lib/               # 依赖jar包
├── META-INF/
│   └── MANIFEST.MF        # 主清单文件
└── org/springframework/boot/loader/  # SpringBoot加载器

分层打包原理:

  • SpringBoot 2.3+支持分层JAR
  • 按依赖变化频率分层:dependencies > spring-boot-loader > snapshot-dependencies > application
  • Docker构建时可缓存不变的层

分层打包配置:

xml
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <layers>
            <enabled>true</enabled>
        </layers>
    </configuration>
</plugin>

Dockerfile优化示例:

dockerfile
FROM java:8-alpine as builder
WORKDIR application
COPY target/app.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract --destination extracted

FROM java:8-alpine
WORKDIR application
COPY --from=builder application/extracted/dependencies/ ./
COPY --from=builder application/extracted/spring-boot-loader/ ./
COPY --from=builder application/extracted/snapshot-dependencies/ ./
COPY --from=builder application/extracted/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

面试回答技巧:核心说"依赖层不变,应用层常变",Docker构建时先复制依赖层可缓存,只有代码变化才重建应用层,大幅减少构建时间。


总结 ​

本批题目覆盖:自动配置原理、配置管理、Bean生命周期、AOP代理、事务传播、多数据源、Actuator监控、分层打包等核心考点。建议结合源码深入理解条件注解和启动流程。