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

发布于:2025-06-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

🤟致敬读者

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

📘博主相关



📃文章前言

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

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

在这里插入图片描述

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


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

    • 核心作用:开启自动配置 + 组件扫描 + 配置类声明
    • 元注解组成:
      @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
    // 示例
    @Autowired @Qualifier("mysqlService") 
    private DataService service1;
    
    @Resource(name = "oracleService") 
    private DataService service2;
    

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

    • @Controller
      • 需要配合 @ResponseBody 返回 JSON
      • 通常返回视图名称
    • @RestController = @Controller + @ResponseBody
      • 所有方法自动 JSON 序列化
    // 传统写法
    @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 表达式
      @Value("${server.port}") 
      private int port;
      
    • @ConfigurationProperties
      • 批量绑定属性到对象
      • 支持类型安全校验
      @ConfigurationProperties(prefix = "datasource")
      public class DataSourceConfig {
          private String url;
          private String username;
          // getters/setters
      }
      
  2. @PropertySource 加载自定义配置的注意事项?

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

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

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

    源码解析

    // 自定义条件
    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 实现异步调用的线程池配置?
    最佳实践

    @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 在类和方法上的优先级?
    规则

    • 方法注解 > 类注解
    • 接口注解无效(需基于类代理)
    @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组件 仓库层测试
    // 控制器测试示例
    @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. 编写自动配置类:
      @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 注册:
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        com.example.MyAutoConfiguration
      
  2. @ControllerAdvice 的三种用法?

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


📜文末寄语

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