zoukankan      html  css  js  c++  java
  • Spring入门--控制反转(IOC)与依赖注入(DI)

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

        控制反转即IoC (Inversion of Control)。它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。

    所谓的“控制反转”概念就是对组件对象控制权的转移。从程序代码本身转移到了外部容器。


        IoC是一个非常大的概念,能够用不同的方式来实现。

    其主要实现方式有两种:<1>依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这样的方式。

    <2>依赖注入(Dependency Injection):组件不做定位查询,仅仅提供普通的Java方法让容器去决定依赖关系。后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor Injection)三种方式。


                                                  图控制反转概念结构

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



    如今来考虑IoC的实现机制,组件定义了整个流程框架,而当中的一些业务逻辑的实现要借助于其它业务对象的增加,它们能够通过两种方式參与到业务流程中,一种是依赖查找(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环境,所以它不能在应用server之外执行,而且假设要用别的方式代替JNDI来查找资源和协作对象,就必须把JNDI代码抽出来重构到一个策略方法中去。


    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类展示了一个业务组件。它的实现须要对象Content的注入。

    代码3。代码4。代码5。6分别演示构造子注入(Constructor Injection),设值注入(Setter Injection)和接口注入(Interface Injection)三种方式。


     
            代码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迈出了一小步。真正的理解,要放在实践中去。

  • 相关阅读:
    传说中的灵感
    错误: Sys.WebForms.PageRequestManagerServerErrorException: 只能在执行 Render() 的过程中调用 RegisterForEventValidation;
    只能在执行 Render() 的过程中调用 RegisterForEventValidation
    在aspx实现用户控件内Web控件的事件
    Asp.net网页上嵌入Media Player播放
    为临时表动态添加字段
    如何防止头文件被重复包含、嵌套包含
    Linux C SQLite3 编程
    Android开源项目源码下载(不断更新中)
    Android程序员必看之Android六大优势
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7106872.html
Copyright © 2011-2022 走看看