微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

依赖注入

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.更符合高内聚的原则。(只有组件的创建者才能改变组件的依赖关系。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐