1. 为什么需要系统化的Spring面试准备
最近帮团队面试了几位Java开发工程师,发现很多候选人对Spring框架的理解停留在表面用法。问到"Bean的生命周期"时,有人直接回答"就是@Autowired注入",这让我意识到系统化整理Spring知识体系的重要性。这份笔记源自我的面试官笔记和候选人常见问题,涵盖从IoC容器到Spring Boot的完整知识链。
2. Spring核心机制深度解析
2.1 IoC容器工作原理
Spring容器的启动流程值得每个Java开发者牢记:
- 资源定位:通过ResourceLoader加载配置文件
- Bean定义载入:将XML/注解配置转换为BeanDefinition
- 注册到容器:BeanDefinitionRegistry完成注册
- 依赖注入:AutowiredAnnotationBeanPostProcessor处理@Autowired
关键点:BeanDefinition是Spring对Bean的"设计图纸",包含类名、作用域、属性值等元数据
2.2 AOP实现原理面试精要
被问到动态代理时,建议按这个思路回答:
- JDK动态代理:基于接口,通过Proxy.newProxyInstance创建
- CGLIB代理:通过继承方式,MethodInterceptor处理调用
- 实际选择:目标类有接口用JDK,否则用CGLIB(可通过proxy-target-class强制)
java复制// 典型面试题:下面配置有什么区别?
@EnableAspectJAutoProxy(proxyTargetClass = false) // 默认
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制CGLIB
3. Spring MVC高频考点剖析
3.1 请求处理全流程
常被要求在白板画出流程,核心步骤包括:
- DispatcherServlet接收请求
- HandlerMapping找到对应Controller
- HandlerAdapter执行方法
- 处理@ResponseBody和视图解析
3.2 参数绑定难点
java复制@GetMapping("/users")
public List<User> getUsers(
@RequestParam(required=false, defaultValue="1") int page, // 分页参数
@DateTimeFormat(pattern="yyyy-MM-dd") Date createTime, // 日期格式化
@Valid UserQuery query) { // 对象绑定
// ...
}
常见坑点:
- 日期格式化需要配合@DateTimeFormat
- 对象绑定支持级联属性(如query.address.city)
- @Valid校验失败会抛出MethodArgumentNotValidException
4. Spring Boot自动配置原理
4.1 @SpringBootApplication背后的魔法
这个复合注解包含三个关键部分:
- @Configuration:标记配置类
- @ComponentScan:包扫描
- @EnableAutoConfiguration:加载META-INF/spring.factories
4.2 条件装配的几种方式
面试常考的条件注解:
- @ConditionalOnClass:类路径存在指定类时生效
- @ConditionalOnMissingBean:容器不存在指定Bean时生效
- @Profile:根据激活的profile决定是否加载
java复制@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
5. 事务管理必知必会
5.1 传播行为实战理解
PROPAGATION_REQUIRED(默认):
- 当前有事务就加入,没有就新建
- 像团队协作:有组长就跟组,没有就自己当组长
PROPAGATION_REQUIRES_NEW:
- 总是新建事务
- 像独立承包商:不管有没有现成团队都自己单干
5.2 隔离级别对比
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 适用场景 |
|---|---|---|---|---|
| READ_UNCOMMITTED | ✓ | ✓ | ✓ | 几乎不用 |
| READ_COMMITTED | × | ✓ | ✓ | Oracle默认 |
| REPEATABLE_READ | × | × | ✓ | MySQL默认 |
| SERIALIZABLE | × | × | × | 金融等高一致性要求场景 |
6. 性能优化相关考点
6.1 Bean作用域选择
- singleton:默认,适合无状态Bean
- prototype:每次注入新实例,适合有状态场景
- request/session:Web环境专用
陷阱:在singleton中注入prototype Bean时,需要用@Lookup或ObjectFactory
6.2 循环依赖解决方案
Spring通过三级缓存解决setter注入的循环依赖:
- singletonObjects:存放完整Bean
- earlySingletonObjects:存放早期引用
- singletonFactories:存放ObjectFactory
构造器注入的循环依赖无法解决,典型报错:
code复制Requested bean is currently in creation: Is there an unresolvable circular reference?
7. 实战问题排查锦囊
最近排查过的一个典型问题:
java复制@Transactional
public void batchCreate(List<User> users) {
users.forEach(userRepository::save); // 每条记录单独提交
// 应该改为userRepository.saveAll(users)
}
问题现象:批量插入性能极差
根本原因:默认事务传播导致每条insert都单独提交
解决方案:改用saveAll或手动flush
8. Spring Cloud相关考点
虽然题目聚焦Spring,但高级岗位常问微服务相关:
- 服务发现:Eureka vs Nacos
- 配置中心:Spring Cloud Config最佳实践
- 熔断降级:Hystrix与Sentinel对比
- 网关路由:Spring Cloud Gateway过滤器链
建议准备2-3个实际遇到的分布式问题案例,比如:
"我们曾用@RefreshScope实现配置热更新,但发现..."
9. 面试实战技巧
最后分享几个回答技巧:
-
被问到原理时,先说应用场景再说实现
- 错误回答:"AOP就是动态代理"
- 正确回答:"比如我们需要做日志监控时,通过AOP可以..."
-
遇到不会的问题时:
"这块我项目中没有直接使用过,但根据我的理解应该是..." -
展示深度的小技巧:
"Spring5之后对@Transactional有个优化,在同类方法调用时..."