spring如何实现运行时的依赖注入? [英] How does spring achieve dependency injection at runtime?

查看:43
本文介绍了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) 再次检查 Database 的实例是否已经可用.

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如何实现运行时的依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆