国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > Spring入门--控制反转(IOC)与依赖注入(DI)

Spring入门--控制反转(IOC)与依赖注入(DI)

来源:程序员人生   发布时间:2014-11-13 08:22:01 阅读次数:2612次

    1.控制反转(Inversion of Control)与依赖注入(Dependency Injection)

    控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。


    IoC是1个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:<1>依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这类方式。<2>依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor Injection)3种方式。


                                              图控制反转概念结构

依赖注入之所以更流行是由于它是1种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBean的setter方法或带参数的构造子或接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:<1>查找定位操作与利用代码完全无关。<2>不依赖于容器的API,可以很容易地在任何容器之外使用利用对象。<3>不需要特殊的接口,绝大多数对象可以做到完全没必要依赖容器。
 
2.好莱坞原则
IoC体现了好莱坞原则,即“不要打电话过来,我们会打给你”。第1次遇到好莱坞原则是在了解模板方法(Template Mathod)模式的时候,模板方法模式的核心是,基类(抽象类)定义了算法的骨架,而将1些步骤延迟到子类中。


现在来斟酌IoC的实现机制,组件定义了全部流程框架,而其中的1些业务逻辑的实现要借助于其他业务对象的加入,它们可以通过两种方式参与到业务流程中,1种是依赖查找(Dependency Lookup),类似与JDNI的实现,通过JNDI来找到相应的业务对象(代码1),另外一种是依赖注入,通过IoC容器将业务对象注入到组件中。

3. 依赖查找(Dependency Lookup)
下面代码展现了基于JNDI实现的依赖查找机制。

public class MyBusniessObject{ private DataSource ds; private MyCollaborator myCollaborator; public MyBusnissObject(){ Context ctx = null; try{ ctx = new InitialContext(); ds = (DataSource) ctx.lookup(“java:comp/env/dataSourceName”); myCollaborator = (MyCollaborator) ctx.lookup(“java:comp/env/myCollaboratorName”); }……

        依赖查找的主要问题是,这段代码必须依赖于JNDI环境,所以它不能在利用http://www.wfuyu.com/server/以外运行,并且如果要用别的方式取代JNDI来查找资源和协作对象,就必须把JNDI代码抽出来重构到1个策略方法中去。

4. 依赖注入(Dependency Injection)
依赖注入的基本原则是:利用组件不应当负责查找资源或其他依赖的协作对象。配置对象的工作应当由IoC容器负责,“查找资源”的逻辑应当从利用组件的代码中抽取出来,交给IoC容器负责。
下面分别演示3中注入机制。
代码2 待注入的业务对象Content.java

package com.zj.ioc.di; public class Content { public void BusniessContent(){ System.out.println("do business"); } public void AnotherBusniessContent(){ System.out.println("do another business"); } }

        MyBusniess类展现了1个业务组件,它的实现需要对象Content的注入。代码3,代码4,代码5,6分别演示构造子注入(Constructor Injection),设值注入(Setter Injection)和接口注入(Interface Injection)3种方式。
 
        代码3构造子注入(Constructor Injection)MyBusiness.java

package com.zj.ioc.di.ctor; import com.zj.ioc.di.Content; public class MyBusiness { private Content myContent; public MyBusiness(Content content) { myContent = content; } public void doBusiness(){ myContent.BusniessContent(); } public void doAnotherBusiness(){ myContent.AnotherBusniessContent(); } }

    代码4设值注入(Setter Injection MyBusiness.java

package com.zj.ioc.di.set; import com.zj.ioc.di.Content; public class MyBusiness { private Content myContent; public void setContent(Content content) { myContent = content; } public void doBusiness(){ myContent.BusniessContent(); } public void doAnotherBusiness(){ myContent.AnotherBusniessContent(); } }

        代码5 设置注入接口InContent.java

package com.zj.ioc.di.iface; import com.zj.ioc.di.Content; public interface InContent { void createContent(Content content); }
    代码6接口注入(Interface InjectionMyBusiness.java

package com.zj.ioc.di.iface; import com.zj.ioc.di.Content; public class MyBusiness implements InContent{ private Content myContent; public void createContent(Content content) { myContent = content; } public void doBusniess(){ myContent.BusniessContent(); } public void doAnotherBusniess(){ myContent.AnotherBusniessContent(); } }

        以上是学习spring的最基本的概念的理解,只是对理解spring迈出了1小步,真实的理解,要放在实践中去。

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生