我读了很多关于此的内容,但我仍然不清楚这些事情。我们说 DI 就是在运行时将依赖注入依赖组件
第一季度
什么是依赖?如果这些是在运行时创建的对象?
如果是,这是否意味着我们通过创建对象将值注入变量(由框架创建,即通过 xml 文件使用 setter/constructor 注入实例化 bean)
第二季度
我们做 DI 是为了在没有对象干预的情况下做工作?
我读了很多关于此的内容,但我仍然不清楚这些事情。我们说 DI 就是在运行时将依赖注入依赖组件
第一季度
什么是依赖?如果这些是在运行时创建的对象?
如果是,这是否意味着我们通过创建对象将值注入变量(由框架创建,即通过 xml 文件使用 setter/constructor 注入实例化 bean)
第二季度
我们做 DI 是为了在没有对象干预的情况下做工作?
从Wikipedia中,DI 模式中的所有元素都是对象。依赖对象使用接口指定它需要什么。注入器对象决定哪些具体类(实例化对象)可以满足需求并将它们提供给依赖对象。
所以,这对第二部分来说是肯定的。
再次来自维基百科:
依赖注入模式的主要目的是允许在运行时或通过配置文件而不是在编译时选择给定依赖接口的多个实现。
作为一个例子,考虑一个安全服务,它可以工作于不同的Encoder
. 不同的编码算法可能包括 SHA、MD5 等。安全服务只指定它需要一个“编码算法”的实例。然后,运行时 DI 环境将寻找提供接口的对象,Encoder
然后将其注入安全服务。与 DI 一致,安全服务也利用了控制反转 (IoC);即,它本身并不决定使用什么实现,而是由 DI 运行时做出决定。
不是一个复杂的答案,让它变得更简单。
问题1:
class Dependent {
propertyA = new PropertyA();
propertyB = new PropertyB();
}
这里Dependent
依赖于propertyA
和propertyB
。上面的关系是依赖的一个例子。
如果这些是在运行时创建的对象?是的。
如是....?是的
问题2:是的。
详情如下
场景一:
class Dependent {
DBConnection connection = new OracleConnection();
}
Dependent
类是高度耦合的。因为除非我们更改代码,否则无法更改连接。因此,如果客户需要 MySQLConnection(),我们将不得不更改代码并给他们另一个 exe/jar。
场景二:
class Dependent {
DBConnection connection = ConnectionFactory.createConnection();
}
这要好得多,因为ConnectionFactory
将能够读取一些配置并创建必要connection
的 .
但是,它仍然对模拟Dependent
课程提出了一些困难。在这些情况下很难创建模拟。然后呢?
场景 3:
class Dependent {
DBConnection connection;
setConnection(DBConnection connection) {
this.connecttion = connection;
}
}
class DependencyInjector {
inject() {
// wire them together every dependent & their dependency!
Dependent dependent = indentiyDepenentSomeSmartWay();
DBConnection connection = indentiyConnectionSomeSmartWay();
dependent.setConnection(connection);
}
}
我们DependencyInjector
是一个聪明的班级,知道所有必要的信息!以上Dependent
课程干净简单。很容易模拟它们进行单元测试,使用配置进行配置。
那些对象创建和耦合是分离的!
用简单的话回答你的问题,
对于#1: 依赖注入是通过给它所需的对象来满足一个对象的需求。让我们看一个例子:
通常在企业应用程序中,我们使用的架构在服务中调用 DAO 层,DAO 完成所有与数据库相关的工作。所以服务需要和DAO的对象调用所有的DAO方法。
考虑到我们有一个实体对象 - Person。
假设我们有一个 DAO - PersonDAO。
public interface PersonDAO {
void addPerson(Person person);
void updatePerson(Person person);
void deletePerson(int personId);
}
和一个服务——PersonService。
public class PersonServiceImpl {
private PersonDAO personDAO;
public void addPerson() {
//some code specific to service.
//some code to create Person obj.
personDAO.add(person);
}
}
如您所见,PersonService 正在使用 PersonDAO 对象来调用其方法。PersonService 依赖于 PersonDAO。所以 PersonDAO 是依赖,而 PersonService 是依赖对象。
通常在像 Spring 这样的框架中,这些依赖项是由框架本身注入的。加载应用程序上下文时,所有这些依赖对象都被创建并放入容器中,并在需要时使用它们。由于依赖对象的创建方式,控制反转(IoC)的概念与依赖注入密切相关。
例如,您可以在 PersonService 本身中将 PersonDAO 对象创建为 PersonDAO personDAO = new PersonDAOImpl();
但是在 spring 的情况下,您只是在 PersonService 中为 PersonDAO 定义一个属性,并为它提供一个 setter,spring 使用它来设置依赖项。这里依赖的创建由框架而不是使用它的类负责,因此它被称为控制反转。
对于#2:是的。你说的对。