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 应用。


📜文末寄语

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

相关推荐
泡海椒1 分钟前
告别反射低效:JQuick-Java ASM动态调用链性能优化实战
java·python·性能优化
土司大王11 分钟前
LeetCode 17 电话号码的字母组合:Java 回溯模板、多叉决策树与复杂度分析
java·leetcode·决策树
行百里er21 分钟前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
spring boot·spring cloud·监控
CoderYanger25 分钟前
前端基础——JavaScript(WebAPI)代码案例
java·开发语言·前端·javascript·css·前端框架·html5
Nuanyt35 分钟前
JUC常见核心知识梳理02 AQS ReentrantLock CAS 原子类 线程池
java
CodeStats38 分钟前
【Java数据类型】Java底层数据类型原理(上):基本类型、转换与封装核心
java·数据类型·string·封装·转换
陈皮波比茶44 分钟前
SpringCloudAlibaba
java·spring cloud·微服务
重生之小比特1 小时前
【Java SE】程序逻辑控制
java·开发语言·python
find1star1 小时前
LeetCode 25:K 个一组翻转链表
java·数据结构·算法·leetcode·链表·职场和发展·动态规划
染的人1 小时前
Java 10x15cm面单PDF转换A4格式PDF
java·开发语言·pdf