How does spring achieve dependency injection at runtime?

百般思念 提交于 2021-02-18 11:36:30

问题


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?


回答1:


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

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.

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.

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.

We register a few classes:

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

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

class EmployeeDao {
   @Inject Database db;
} 

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) A check is done if there already exists an instance of EmployeeDao, if so it is returned.

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) Again a check is done if an instance of Database is already available.

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) A Database instance is returned.

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) The EmployeeDao instance, now fully injected, is returned.

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.



来源:https://stackoverflow.com/questions/43514699/how-does-spring-achieve-dependency-injection-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!