依赖注入

来源:互联网 发布:打印机网络共享 编辑:程序博客网 时间:2024/05/22 12:58
DI(依赖注入,Dependency Injection)== IoC(控制反转,Inversion of Control).
在当某个java实例(调用者)需要另一个java实例(被调用者)时,在传统的程序设计过程中,通常是有调用者来创建被调用者的实例。
在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此叫做控制反转。这个创建的实例是由spring容器来完成,然后注入调用者,称为依赖注入。

例子:一个人(java实例,调用者)需要一把斧子(java实例,被调用者)

(1)原始社会:需要斧子的人(调用者)只能自己去磨一把斧子(被调用者)
通常采用new调用构造器创建一个被调用者。
(2)工业社会:工厂模式,需要斧子的人(调用者)找到工厂,购买斧子,无需关心斧子的制造过程。(简单的工厂设计模式)。(定位工厂,无需关心具体的实现。)
(3)共产社会:无需定位工厂,‘坐等’社会提供即可。无需关心调用者的实现,无需理会工厂,等待spring依赖注入。
(1)1.程度高度耦合,效率低下。(可扩展性差(由于高度吻合,修改斧头组件,‘人’的代码也改变)
2.各组件职责不清,只要关心组件的方法,不关心创建过程。)
(2)此时无需关心被调用者的具体实习过程,只需要找到符合某种标准(接口)的实例,这个是面向接口的编程,可以让调用者和被调用者解耦。调用者依旧需要主动定位工厂,调用者与工厂耦合在一起。
DI:是指程序运行过程中,如果需要另一个对象协作(调用方法,访问属性)时,无须再代码中创建被调用者,而是依赖于外部容器的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持POJO之间依赖关系的管理。

DI分为两种1.设值注入(IoC容器使用属性的setter方法来注入被依赖的实例),
2.构造注入(IoC容器使用构造器来注入被依赖的实例)
1.在spring中的配置如下所示,需要在具体的实现类中调用这个id,生成set方法后,调用这个东西。

<!-- 配置名为person的Bean,其实现类是org.crazyit.app.service.Person类 -->
<bean id="person" class="org.crazyit.app.service.Person">
<!-- 控制调用setAxe()方法,将容器中axe Bean作为传入参数 -->
<property name="axe" ref="axe"/>
</bean>
<!-- 配置名为axe的Bean,其实现类是org.crazyit.app.service.Axe类 -->
<bean id="axe" class="org.crazyit.app.service.Axe"/>
<!-- 配置名为win的Bean,其实现类是javax.swing.JFrame类 -->
<bean id="win" class="javax.swing.JFrame"/>
<!-- 配置名为date的Bean,其实现类是java.util.Date类 -->
<bean id="date" class="java.util.Date"/>
2.在构造实例的过程中,已经完成了依赖关系的初始化。

public class Chinese implements Person
{
private Axe axe;
// 构造注入所需的带参数的构造器
public Chinese(Axe axe)
{
this.axe = axe;
}
// 实现Person接口的useAxe()方法
public void useAxe()
{
// 调用axe的chop()方法
// 表明Person对象依赖于axe对象
System.out.println(axe.chop());
}
}

<!-- 配置chinese实例,其实现类是Chinese -->
<bean id="chinese" class="org.crazyit.app.service.impl.Chinese">
<!-- 下面只有一个constructor-arg子元素,
驱动Spring调用Chinese带一个参数的构造器来创建对象 -->
<constructor-arg ref="steelAxe" type="org.crazyit.app.service.Axe"/>
</bean>
<!-- 配置stoneAxe实例,其实现类是StoneAxe -->
<bean id="stoneAxe" class="org.crazyit.app.service.impl.StoneAxe"/>
<!-- 配置steelAxe实例,其实现类是SteelAxe -->
<bean id="steelAxe" class="org.crazyit.app.service.impl.SteelAxe"/>


设值注入是先通过无参数的构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则直接调用有参数的构造器,当Bean'实例创建完成后,已经完成了依赖关系的注入。
两种注入方式适用范围不同。

(1)设值注入的优点:1.更加易于理解,接受。2.复杂依赖关系时,设值相对于构造性能更好。(初始化依赖减少)。(3)某些属性可选的情况下,多参数的构造器比较笨重。
(2)构造注入的优点:1.可以决定依赖关系的注入顺序,优先依赖的优先注入。2.更符合高内聚的原则。(只有组件的创建者才能改变组件的依赖关系。)
原创粉丝点击