Spring Boot 常用注解面试题深度解析

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关


文章目录


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

Spring Boot 常用注解面试题深度解析

以下精选 25+ 高频注解面试题,涵盖核心原理、实战技巧及源码级分析,助你轻松应对面试挑战。


一、核心启动注解(必考)
  1. @SpringBootApplication 的作用是什么?包含哪些关键注解?

    • 核心作用:开启自动配置 + 组件扫描 + 配置类声明

    • 元注解组成:

      java 复制代码
      @SpringBootConfiguration  // 声明为配置类
      @EnableAutoConfiguration  // 启用自动配置
      @ComponentScan            // 包扫描(默认当前包及其子包)
  2. @EnableAutoConfiguration 如何实现自动装配?

    1. 加载 META-INF/spring.factories 中的配置类

    2. 通过 @Conditional 系列注解按条件装配 Bean

    3. 核心流程:

      graph LR A[启动类] --> B[@SpringBootApplication] B --> C[@EnableAutoConfiguration] C --> D[AutoConfigurationImportSelector] D --> E[加载spring.factories] E --> F[过滤@Conditional条件] F --> G[注册Bean定义]

二、Bean 管理与依赖注入
  1. @Component@Bean 的区别?
    对比表

    特性 @Component @Bean
    作用目标 类声明 方法声明
    控制权 Spring 自动实例化 开发者手动创建对象
    适用场景 自定义类 第三方库组件
    依赖注入 支持 @Autowired 需在配置类中使用
  2. @Autowired@Resource 的区别?

    • @Autowired
      • 按类型注入 → byType
      • 支持 @Qualifier 指定名称
      • 是 Spring 原生注解
    • @Resource
      • 默认按名称注入 → byName(失败时回退到 byType)
      • JDK 原生注解(javax.annotation
    java 复制代码
    // 示例
    @Autowired @Qualifier("mysqlService") 
    private DataService service1;
    
    @Resource(name = "oracleService") 
    private DataService service2;

三、Spring MVC 注解
  1. @RestController@Controller 的区别?

    • @Controller
      • 需要配合 @ResponseBody 返回 JSON
      • 通常返回视图名称
    • @RestController = @Controller + @ResponseBody
      • 所有方法自动 JSON 序列化
    java 复制代码
    // 传统写法
    @Controller
    public class OldController {
        @ResponseBody
        public User getUser() { /* ... */ }
    }
    
    // 现代写法
    @RestController
    public class NewController {
        @GetMapping("/user")
        public User getUser() { /* ... */ } // 自动转JSON
    }
  2. @PathVariable@RequestParam 的应用场景?
    对比

    注解 位置 示例 URL 获取方式
    @PathVariable URL 路径 /users/{id} id = 123
    @RequestParam 查询字符串 /search?keyword=Spring keyword = "Spring"

四、配置与属性绑定
  1. @Value@ConfigurationProperties 如何选择?

    • @Value

      • 适合单个属性注入
      • 支持 SpEL 表达式
      java 复制代码
      @Value("${server.port}") 
      private int port;
    • @ConfigurationProperties

      • 批量绑定属性到对象
      • 支持类型安全校验
      java 复制代码
      @ConfigurationProperties(prefix = "datasource")
      public class DataSourceConfig {
          private String url;
          private String username;
          // getters/setters
      }
  2. @PropertySource 加载自定义配置的注意事项?

    • 默认不支持 YAML 文件(需配合 YamlPropertySourceFactory
    • 多文件加载顺序决定属性覆盖关系
    java 复制代码
    @Configuration
    @PropertySource(value = "classpath:custom.properties", 
                    encoding = "UTF-8")
    public class AppConfig { /* ... */ }

五、高级特性注解
  1. @Conditional 系列注解的工作原理?(重点)
    核心条件注解

    注解 激活条件
    @ConditionalOnClass 类路径存在指定类
    @ConditionalOnBean Spring 容器存在指定 Bean
    @ConditionalOnProperty 配置属性匹配条件
    @ConditionalOnWebApplication 当前是 Web 应用

    源码解析

    java 复制代码
    // 自定义条件
    public class EnvCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            String env = context.getEnvironment().getProperty("app.env");
            return "prod".equals(env);
        }
    }
    
    // 使用示例
    @Bean
    @Conditional(EnvCondition.class)
    public Service prodService() { /* ... */ }
  2. @Async 实现异步调用的线程池配置?
    最佳实践

    java 复制代码
    @Configuration
    @EnableAsync
    public class AsyncConfig {
        @Bean(name = "taskExecutor")
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(10);
            executor.setQueueCapacity(100);
            executor.setThreadNamePrefix("Async-");
            return executor;
        }
    }
    
    // 使用
    @Service
    public class EmailService {
        @Async("taskExecutor") // 指定线程池
        public void sendEmail() { /* ... */ }
    }

六、事务与测试
  1. @Transactional 在类和方法上的优先级?
    规则

    • 方法注解 > 类注解
    • 接口注解无效(需基于类代理)
    java 复制代码
    @Service
    @Transactional // 类级别默认事务
    public class UserService {
        public void updateProfile() { /* 使用类事务 */ }
        
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void auditLog() { /* 独立事务 */ }
    }
  2. @SpringBootTest@WebMvcTest 的区别?
    对比

    测试注解 测试范围 启动容器 适用场景
    @SpringBootTest 完整集成测试 服务层/DAO层测试
    @WebMvcTest 仅Web MVC层 控制器单元测试
    @DataJpaTest 仅JPA组件 仓库层测试
    java 复制代码
    // 控制器测试示例
    @WebMvcTest(UserController.class)
    public class UserControllerTest {
        @Autowired MockMvc mvc;
        @MockBean UserService userService;
        
        @Test
        void getUserTest() throws Exception {
            mvc.perform(get("/users/1")).andExpect(status().isOk());
        }
    }

七、生产实践与高频问题
  1. 如何自定义 Starter?
    关键步骤

    1. 创建 xxx-spring-boot-autoconfigure 模块

    2. 编写自动配置类:

      java 复制代码
      @Configuration
      @ConditionalOnClass(MyService.class)
      @EnableConfigurationProperties(MyProperties.class)
      public class MyAutoConfiguration {
          @Bean
          @ConditionalOnMissingBean
          public MyService myService(MyProperties props) {
              return new MyService(props);
          }
      }
    3. META-INF/spring.factories 注册:

      properties 复制代码
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        com.example.MyAutoConfiguration
  2. @ControllerAdvice 的三种用法?

    java 复制代码
    @ControllerAdvice
    public class GlobalHandler {
        // 1. 异常处理
        @ExceptionHandler(NotFoundException.class)
        public ResponseEntity<Error> handleNotFound(NotFoundException ex) {
            return ResponseEntity.status(404).body(new Error(ex.getMessage()));
        }
        
        // 2. 数据绑定预处理
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            binder.registerCustomEditor(Date.class, new CustomDateEditor(...));
        }
        
        // 3. 模型数据增强
        @ModelAttribute
        public void addCommonModel(Model model) {
            model.addAttribute("appName", "MyApp");
        }
    }

高频面试题汇总
  1. @SpringBootApplication 的三个核心注解分别起什么作用?
  2. @Autowired 注入失败有哪些可能原因? 答:未扫描包、多个实现类未限定、Bean未创建、静态字段注入等
  3. 如何让 @Scheduled 定时任务在集群中只执行一次? 答:配合 @ConditionalOnProperty 或分布式锁(如 Redis Lock)
  4. @Transactional 失效的常见场景? 答:自调用、非 public 方法、异常类型错误、数据库引擎不支持
  5. @RequestParam vs @RequestBody 的区别? 答:前者处理 URL 参数,后者处理 JSON/XML 请求体

总结:Spring Boot 注解学习路径

  1. 基础层
    • 启动注解:@SpringBootApplication
    • Bean 管理:@Component, @Bean, @Autowired
  2. Web 层
    • REST 控制:@RestController, @GetMapping
    • 参数处理:@PathVariable, @RequestBody
  3. 数据层
    • 数据访问:@Repository, @Transactional
    • 配置绑定:@ConfigurationProperties
  4. 高级特性
    • 条件装配:@Conditional 系列
    • 异步处理:@Async, @EnableAsync
  5. 测试与生产
    • 测试切片:@WebMvcTest, @DataJpaTest
    • 全局处理:@ControllerAdvice, @RestControllerAdvice

掌握这些注解的原理和应用场景,不仅能轻松应对面试,更能构建健壮高效的 Spring Boot 应用。


📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

相关推荐
论迹3 分钟前
【JavaEE】-- HTTP
java·http·java-ee
异常君15 分钟前
ZooKeeper ACL 权限模型详解:实现递归权限管理的有效方案
java·spring boot·zookeeper
眠修1 小时前
NoSQL 之 Redis 集群
java·redis·nosql
异常君1 小时前
Apache Curator LeaderSelector:构建高可用分布式领导者选举机制
java·zookeeper·面试
KotlinKUG贵州1 小时前
Spring开发,从Kotlin开始
spring boot·spring·kotlin
程序员JerrySUN2 小时前
深入理解Linux DRM显示子系统:架构、实战项目与关键问题全解析
linux·运维·服务器·面试·职场和发展·架构
codeRichLife2 小时前
Mybatisplus3.5.6,用String处理数据库列为JSONB字段
java·数据库
来自星星的猫教授2 小时前
Java 文件注释规范(便于生成项目文档)
java·注释
zhimeng32 小时前
自己学习原理
java
程序员鱼皮2 小时前
学 Java 还是 Go 语言?这事儿很简单!
java·后端·计算机·程序员·开发·编程经验·自学编程