gpt4 book ai didi

java - spring是如何实现运行时的依赖注入(inject)的?

转载 作者:搜寻专家 更新时间:2023-10-31 08:31:46 24 4
gpt4 key购买 nike

有谁知道spring用什么技术实现运行时的依赖注入(inject)?它是简单地使用方面 (AOP) 还是更复杂的东西?

最佳答案

Spring 做了很多事情,但依赖注入(inject)本身实际上是一种非常简单的机制。

首先要为可用于注入(inject)的类注册。使用反射检查添加到此注册表中的类。 DI 框架将寻找相关的注释和构造函数来确定如何构造类的实例以及这些类可能需要的其他依赖项。

注册表还会跟踪已创建的实例,以便可以重复使用它们。重用实例涉及范围界定,它确定何时可以重用实例。使用单例(Spring 的默认设置)实例可以不受限制地重复使用。

要创建具有依赖关系的类的实例,使用反射来创建实例。如果需要任何依赖项,则首先创建这些依赖项(如果尚未创建)可能会触发大量实例的递归创建。如果无法创建任何依赖项或存在多个可能的候选者,则框架会抛出异常以指示您的配置存在问题。

一个简单的例子,假设我们有一个 Injector 类,它既充当类的注册中心,又充当创建新实例的手段。

我们注册了几个类:

injector.register(Database.class);
injector.register(EmployeeDao.class);

假设数据库类没有进一步的依赖关系,而 EmployeeDao 依赖于数据库:

class EmployeeDao {
@Inject Database db;
}

注入(inject)器通过反射知道EmployeeDao依赖于Database。当我们向 injector 请求 EmployeeDao 的实例时,会发生以下情况:

EmployeeDao employeeDao = injector.getInstance(EmployeeDao.class);

1) 检查是否已经存在 EmployeeDao 实例,如果存在则返回。

2) 如果不是,则检查构建EmployeeDao 需要什么,在本例中它需要一个Databaseinjector 递归调用自身:

Database database = injector.getInstance(Database.class);

2a) 再次检查 Database 的实例是否已经可用。

2b) 构建Database不需要进一步的依赖,所以injector调用Database.class.newInstance()并保持跟踪它。

2c) 返回一个Database实例。

3) Database 实例可用后,injector 现在可以构造EmployeeDao:EmployeeDao.class.newInstance() -- 在反射的帮助下,字段 database 被注入(inject)了 Database 实例。

4) 现在完全注入(inject)的 EmployeeDao 实例被返回。

这是获取类实例的相当直接的方式,但这是像 Spring 这样的 DI 框架的核心工作方式。更高级的功能需要创建动态代理和使用 AOP,但 DI 本身归结为使用反射自动构造实例。

关于java - spring是如何实现运行时的依赖注入(inject)的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43514699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com