致敬读者
博主相关
文章前言
以下精选 25+ 高频注解面试题,涵盖核心原理、实战技巧及源码级分析,助你轻松应对面试挑战。
@SpringBootApplication
的作用是什么?包含哪些关键注解?
答:
@SpringBootConfiguration // 声明为配置类
@EnableAutoConfiguration // 启用自动配置
@ComponentScan // 包扫描(默认当前包及其子包)
@EnableAutoConfiguration
如何实现自动装配?
答:
META-INF/spring.factories
中的配置类@Conditional
系列注解按条件装配 Beangraph LR
A[启动类] --> B[@SpringBootApplication]
B --> C[@EnableAutoConfiguration]
C --> D[AutoConfigurationImportSelector]
D --> E[加载spring.factories]
E --> F[过滤@Conditional条件]
F --> G[注册Bean定义]
@Component
与 @Bean
的区别?
对比表:
特性 | @Component |
@Bean |
---|---|---|
作用目标 | 类声明 | 方法声明 |
控制权 | Spring 自动实例化 | 开发者手动创建对象 |
适用场景 | 自定义类 | 第三方库组件 |
依赖注入 | 支持 @Autowired |
需在配置类中使用 |
@Autowired
和 @Resource
的区别?
答:
@Autowired
:
byType
@Qualifier
指定名称@Resource
:
byName
(失败时回退到 byType)javax.annotation
)// 示例
@Autowired @Qualifier("mysqlService")
private DataService service1;
@Resource(name = "oracleService")
private DataService service2;
@RestController
和 @Controller
的区别?
答:
@Controller
:
@ResponseBody
返回 JSON@RestController
= @Controller
+ @ResponseBody
// 传统写法
@Controller
public class OldController {
@ResponseBody
public User getUser() { /* ... */ }
}
// 现代写法
@RestController
public class NewController {
@GetMapping("/user")
public User getUser() { /* ... */ } // 自动转JSON
}
@PathVariable
与 @RequestParam
的应用场景?
对比:
注解 | 位置 | 示例 URL | 获取方式 |
---|---|---|---|
@PathVariable |
URL 路径 | /users/{id} |
id = 123 |
@RequestParam |
查询字符串 | /search?keyword=Spring |
keyword = "Spring" |
@Value
与 @ConfigurationProperties
如何选择?
答:
@Value
:
@Value("${server.port}")
private int port;
@ConfigurationProperties
:
@ConfigurationProperties(prefix = "datasource")
public class DataSourceConfig {
private String url;
private String username;
// getters/setters
}
@PropertySource
加载自定义配置的注意事项?
答:
YamlPropertySourceFactory
)@Configuration
@PropertySource(value = "classpath:custom.properties",
encoding = "UTF-8")
public class AppConfig { /* ... */ }
@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() { /* ... */ }
@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() { /* ... */ }
}
@Transactional
在类和方法上的优先级?
规则:
@Service
@Transactional // 类级别默认事务
public class UserService {
public void updateProfile() { /* 使用类事务 */ }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void auditLog() { /* 独立事务 */ }
}
@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());
}
}
如何自定义 Starter?
关键步骤:
xxx-spring-boot-autoconfigure
模块@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyProperties props) {
return new MyService(props);
}
}
META-INF/spring.factories
注册:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
@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");
}
}
@SpringBootApplication
的三个核心注解分别起什么作用?@Autowired
注入失败有哪些可能原因?
答:未扫描包、多个实现类未限定、Bean未创建、静态字段注入等
@Scheduled
定时任务在集群中只执行一次?
答:配合
@ConditionalOnProperty
或分布式锁(如 Redis Lock)
@Transactional
失效的常见场景?
答:自调用、非 public 方法、异常类型错误、数据库引擎不支持
@RequestParam
vs @RequestBody
的区别?
答:前者处理 URL 参数,后者处理 JSON/XML 请求体
@SpringBootApplication
@Component
, @Bean
, @Autowired
@RestController
, @GetMapping
@PathVariable
, @RequestBody
@Repository
, @Transactional
@ConfigurationProperties
@Conditional
系列@Async
, @EnableAsync
@WebMvcTest
, @DataJpaTest
@ControllerAdvice
, @RestControllerAdvice
掌握这些注解的原理和应用场景,不仅能轻松应对面试,更能构建健壮高效的 Spring Boot 应用。
文末寄语