本文介绍了spring如何在运行时实现依赖注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道spring在运行时使用什么技术来实现依赖注入吗?它只是使用方面(AOP)还是更复杂?

Does anyone know what technique spring uses to achieve dependency injection at runtime? Does it simply use aspects (AOP) or is it something more complicated?

推荐答案

Spring做了很多事情,但是依赖注入本身实际上是一个非常简单的机制.

Spring does a lot of things, but dependency injection itself is actually a surprisingly simple mechanism.

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

It starts with having a registry for classes that are available for injection.Classes that are added to this registry are examined using reflection. A DI framework will look for relevant annotations and constructors to determine how to construct instances of the classes and also what other dependencies these classes may need.

注册表还跟踪已创建的实例,以便可以重复使用它们.重用实例涉及作用域,这确定了何时可以重用实例.有了单例(Spring的默认设置),实例可以不受限制地重复使用.

The registry also keeps track of already created instances so they can be re-used. Re-using instances involves scoping, which determines when an instance can be re-used. With singletons (the default for Spring) instances can be re-used without restriction.

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

To create an instance of class with dependencies, reflection is used to create an instance. If there are any dependencies required, those are created first (if not already created) potentially triggering a lot of recursive creation of instances. If any of the dependencies cannot be created or there are multiple possible candidates, the framework can throw an exception to indicate a problem in your configuration.

一个简单的例子,假设我们有一个 Injector 类,它既充当类的注册表,又充当创建新实例的方式.

A simple example, let's say we have an Injector class that acts as both registry of classes and as a means to create new instances.

我们注册了一些课程:

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

我们假设Database类没有进一步的依赖关系,而EmployeeDao对Database具有依赖关系:

Let's assume the Database class has no further dependencies, and EmployeeDao has a dependency on Database:

class EmployeeDao {
   @Inject Database db;
}

injector 通过反射的方式知道 EmployeeDao Database 有依赖性.当我们向 injector 询问 EmployeeDao 的实例时,会发生以下情况:

The injector, by means of reflection, knows that EmployeeDao has a dependency on Database. When we ask the injector for an instance of EmployeeDao the following happens:

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

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

1) A check is done if there already exists an instance of EmployeeDao, if so it is returned.

2)如果不是,则进行检查以查看构造 EmployeeDao 所需的内容,在这种情况下,它需要一个 Database . injector 通过以下方式递归调用自身:

2) If not, a check is done to see what is needed to construct EmployeeDao, in this case it needs a Database. The injector calls itself recursively with:

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

2a)再次检查数据库的实例是否可用.

2a) Again a check is done if an instance of Database is already available.

2b)不需要进一步的依赖来构造 Database ,因此 injector 调用 Database.class.newInstance()并保持跟踪它.

2b) There are no further dependencies required in order to construct Database so the injector calls Database.class.newInstance() and keeps track of it.

2c)返回一个 Database 实例.

2c) A Database instance is returned.

3)有了 Database 实例, injector 现在可以构造 EmployeeDao : EmployeeDao.class.newInstance()-在反射的帮助下,将 Database 字段与 Database 实例一起注入.

3) With the Database instance available, the injector can now construct the EmployeeDao: EmployeeDao.class.newInstance() -- with the help of reflection, the field database is injected with the Database instance.

4)返回现在已完全注入的 EmployeeDao 实例.

4) The EmployeeDao instance, now fully injected, is returned.

这是获取类实例的直接方法,但这是像Spring这样的DI框架如何工作的核心.更高级的功能需要创建动态代理并使用AOP,但DI本身可以归结为使用反射自动构建实例.

This is fairly direct way of obtaining an instance of a class, however this is at the core how DI frameworks like Spring work. More advanced features require creation of dynamic proxies and the use of AOP, but DI itself boils down to using reflection to construct instances automatically.

这篇关于spring如何在运行时实现依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 06:25