Spring中的依赖注入是如何工作的?

19

我想了解Spring如何进行依赖注入,并且想知道其底层逻辑。

更新:

我想了解对象引用是如何注入到构造函数或设置器方法中的,是通过反射还是一些字节码级别的方式。


5
您可以阅读这段代码,因为它是开源的。 - Preet Sangha
@Preet 无论如何,我正在阅读它。我只想要一个概述。 - Dead Programmer
2
我在别处得到了答案,答案是字节码注入。- 不,不是的。Spring 在95%的情况下使用反射API。字节码注入仅用于特定类型的注入,例如方法查找注入。 - Henryk Konsek
1
@henry,你是正确的,字节仪表是用于Spring AOP的。 - Dead Programmer
这是近来面试官最喜欢问的问题。 - Sam2016
2个回答

16
Java组件/类应尽可能独立于其他Java类。这增加了重用这些类并独立于其他类(Unit Testing)测试它们的可能性。为了将Java组件与其他Java组件解耦,依赖于某个其他类的依赖关系应注入到它们中,而不是类本身创建/查找此对象。
如果使用依赖注入,那么通过类A的构造函数将类B提供给类A——这称为构造注入;或通过setter——这称为setter注入,类A对类B具有依赖性,如果类A将类B用作变量。
依赖注入的一般概念称为控制反转。一个类不应配置自己,而应该从外部进行配置。
基于独立类/组件的设计增加了软件的可重用性和测试可能性。例如,如果类A期望Dao(数据访问对象)来接收来自数据库的数据,则可以轻松地创建另一个测试对象,以模拟数据库连接,并将此对象注入A中以测试A,而无需实际数据库连接。
基于依赖注入的软件设计在标准Java中是可能的。
Spring通过提供提供配置的标准方式和管理对创建的对象的引用,简化了使用依赖注入的过程。
阅读更多请参考this编辑1:

当Spring初始化其上下文时,它会创建在Spring应用程序context.xml文件中定义的所有急切地定义的bean。 现在假设你的Bean A有依赖于B,那么B的对象已经由Spring创建成功并存在。然后Spring将在A类中搜索setter方法,并将B的对象设置在那里。

Edit2:

请阅读5.4.1 Setter Injection


2
我正在询问“你是如何在构造函数中注入的”。 - Dead Programmer
@org.life.java 谢谢,你已经完成了 90%,但是如何在运行时“搜索类A中的setter方法”呢? - Dead Programmer
我们已经在应用程序context.xml文件中进行了配置,因此它将查找类的属性,并为此查找标准setter。 - jmj
@org.life.java请以技术角度表达,对于标准制定者来说它是什么样子的。 - Dead Programmer
@DeadProgrammer,你有没有得到自己的问题“你是如何在构造函数中进行注入”的答案? - Parasu

12

Spring DI 引擎从 XML、注解或 Java DSL(JavaConfig)中读取依赖项的配置,然后根据配置中的元数据,使用 Java 反射 API 进行依赖注入。


2
我想知道它如何连接依赖关系。 - Dead Programmer
1
使用Java反射API。我已将该信息添加到答案中。 - Henryk Konsek
1
使用Java反射API,Spring将理解它必须在特定点插入依赖项,但是这个依赖项究竟是如何插入的呢?这是一些字节码级别的更改吗? - flash
1
实际的注入也是通过反射API执行的 - 方法setFooMethod = class.getMethod("setFoo", Foo.class); setFooMethod.invoke(newObject, fooToInject); - Henryk Konsek
我在这里和那里看到了代理的提及,如果是通过反射完成的,为什么我们需要需要接口的代理呢? - Amanuel Nega
所以这就是我的理解, Spring通过Class.forName(...)加载任何类。 在加载新对象时,依赖项通过构造函数参数传递或一旦加载了依赖项,使用反射API进行注入。对于@ Transactional等特殊情况,它使用代理方法将主对象包装在代理对象中。类似地,对于AOP,它使用字节码操作的运行时织入来将其编织到代理对象中。 - Sariq Shaikh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接