这道“依赖注入”的面试题,差点把我从大厂门口打回培训班!

89 阅读5分钟



“同学,能不能讲讲你对Spring的依赖注入的理解?”

这句话你是不是在面试中听到过很多次?

没错,我上周刚经历了一场让人汗毛直立的Java社招面试,结果卡在了—— “什么是Spring的依赖注入” 这道看似简单、实则深水的大题上。

那天的我,穿着干净的衬衫,满脸自信地坐在某十八线大厂的面试间里,结果刚坐下不到十分钟,面试官微微一笑,“聊聊Spring的IOC吧。”

我心想,这不是入门题嘛?然后啪啦啪啦讲了一通:

“Spring的IOC容器是控制反转的体现,它可以帮助我们自动装配Bean,实现解耦……”

结果刚说完,面试官一句话把我打回原形:

“你说了控制反转,那依赖注入是什么?它跟IOC一样吗?”

我当场愣住,冷汗冒出来。接下来半小时,成了灵魂拷问之旅……

小故事:依赖注入是怎么打脸我的?

说来惭愧,虽然我平时工作中天天写@Autowired,但真让我深讲这个注解背后的原理、IOC容器的创建流程、依赖注入的类型……我的脑子就变成了泡面。

于是我带着这道题和我的残余自尊,回家开了一晚上的debug,终于理清楚了“依赖注入”的底层逻辑。

今天,我就以这个故事为契机,把我踩过的坑和学到的精华统统分享出来!

一句话解释:依赖注入是控制反转的一种实现方式!

  • 控制反转(Inversion of Control, IOC) 是一种设计思想。
  • 依赖注入(Dependency Injection, DI) 是实现控制反转的具体技术手段。

很多小伙伴容易把IOC和DI混为一谈,这其实是“概念”与“实现”的关系。

通俗点讲:

  • IOC就像是“你把控制权交出去”,以前你new对象,现在框架帮你new;
  • 而依赖注入,就是Spring用来帮你把这些对象装配好的一种方式。

它们之间的关系就像:

“我决定不自己做饭了”(IOC) → “我点了外卖,外卖小哥送到家里”(DI)

再讲清楚点,什么是依赖注入?

来看个简单例子。

以前我们写代码可能是这样的:

但在Spring里,我们更推荐这样写:

这就是依赖注入的体现

  • UserService依赖于UserRepository;
  • 这个依赖关系不是由UserService主动创建(new),而是Spring框架在后台给它注入的。

Spring是怎么实现依赖注入的?

我们来扒一扒Spring的底层:

1. Bean定义

Spring启动时会扫描你的配置类或XML文件,找到所有的Bean定义,比如:

或者传统的XML配置:

2. 创建对象(实例化)

Spring会通过反射创建这些类的对象。注意:这一步还没有注入依赖!

3. 注入依赖

接下来,Spring会根据注解或者XML配置,把其他依赖注入进去,比如:

  • 属性注入(最常见的,@Autowired)
  • 构造器注入(推荐)
  • Setter注入(老旧代码中较多)

比如构造器注入:

Spring会自动找到PaymentService的Bean,把它注入到OrderService中。

面试中怎么回答“Spring的依赖注入”?

我整理了一份面试回答模板,分享给你:

面试高能回答版:

在Spring中,依赖注入(Dependency Injection)是一种实现控制反转(IOC)的技术手段。通过将对象所依赖的资源(如其他Bean)交由Spring容器管理,从而解耦组件之间的关系,提升系统的可维护性和扩展性。

Spring主要支持三种依赖注入方式:

构造器注入(推荐方式,适用于必填依赖,利于单元测试)

Setter方法注入(适用于可选依赖)

字段注入(使用@Autowired注解,最简便,但不利于测试)

Spring容器在初始化时,会扫描并注册所有的Bean定义,然后根据依赖关系完成注入,依赖查找使用的是类型优先的方式,必要时可结合@Qualifier、@Primary来解决冲突。

延伸面试问题合集

你以为答完依赖注入就完了?不,真正可怕的是面试官的后续追问!

以下问题,我统统经历过:

  • @Autowired是按什么规则注入的?按类型还是按名称?
  • 如果多个同类型Bean,Spring如何决定注入哪一个?
  • @Autowired和@Resource的区别是什么?
  • 构造器注入和字段注入优劣对比?
  • Spring中依赖注入的底层原理是如何实现的?(谈反射、BeanFactory、DefaultListableBeanFactory)
  • Spring Boot如何自动完成依赖注入的?
  • 如何解决循环依赖的问题?

所以,你要做的不是只懂@Autowired怎么写,而是要“知其然,知其所以然”。

实战演练:自己动手写个简易版IOC容器

要真正理解依赖注入,强烈推荐你写一遍“迷你Spring”。

看个极简例子:

然后:

这就是最简单的“手动IOC”模型!

你能从这个实验中感受到依赖注入的本质:创建对象 → 注册到容器 → 从容器获取 → 注入使用

总结一下

最后小米想说

其实,“依赖注入”并不难,但难在我们太容易陷入“写得出来就懂了”的错觉。真正深入理解它,需要我们了解设计理念、底层实现、使用场景、注解原理,甚至再往下看Spring源码中的AutowiredAnnotationBeanPostProcessor。

不要怕复杂,面试就是在拆你会不会把日常代码写得清楚,也能讲得清楚。

我31岁了,还在社招面试中被“依赖注入”拷打,我知道这很痛,但也很有价值。

只要我们继续学习和输出,技术这条路永远都能走下去!

END

如果你也在准备面试,不妨点个“在看”支持一下;留言说说你遇到过的最刁钻面试题,我来陪你一起解析!

我们下篇文章见~

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!