Java 面试题:Spring IOC/AOP 与循环依赖

一、IOC:控制反转与依赖注入

IOC 把对象的创建和依赖关系交给容器管理,开发者只声明”要什么”,容器负责装配。依赖注入三种方式:

方式 特点
构造器注入 不可变、必填,推荐
setter 注入 可选、易变
字段注入 简洁但难测试、不推荐

二、Bean 作用域与生命周期

  • singleton(默认):容器中一个实例;prototype:每次取都新建;还有 request/session 等 Web 作用域;
  • 生命周期:实例化 → 属性填充 → BeanNameAware 等回调 → @PostConstruct → 初始化 → 使用中 → @PreDestroy 销毁。

三、循环依赖与三级缓存

Spring 用三级缓存解决单例 setter/字段注入的循环依赖:

一级: singletonObjects      成品 Bean
二级: earlySingletonObjects  早期暴露(已实例化未填充)
三级: singletonFactories     早期工厂(生成代理)

关键点:构造器注入无法解决循环依赖(会直接抛 BeanCurrentlyInCreationException);用 @Lazy 可打破。

四、AOP:面向切面

把日志、事务、鉴权等”横切关注点”抽出来。Spring AOP 基于动态代理:

代理方式 条件
JDK 动态代理 目标实现接口
CGLIB 无接口或对类代理(生成子类)

通知类型:@Before @After @Around @AfterReturning @AfterThrowing。事务 @Transactional 本质就是 AOP,注意同类方法内部调用会失效(代理没介入)。

五、答题要点

Spring 面试重”原理 + 边界”:循环依赖为什么三级缓存、AOP 代理选择、事务失效场景——能讲清实现机制比背定义更值钱。