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

——摘自Rocky Ren的笔记

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)三种方式。

图1 控制反转概念结构

依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBean的setter方法或者带参数的构造子或者接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:<1>查找定位操作与应用代码完全无关。<2>不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。<3>不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

2.好莱坞原则

IoC体现了好莱坞原则,即“不要打电话过来,我们会打给你”。第一次遇到好莱坞原则是在了解模板方法(Template Mathod)模式的时候,模板方法模式的核心是,基类(抽象类)定义了算法的骨架,而将一些步骤延迟到子类中。

图2 模板方法模式类图

现在来考虑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”);

}……

代码1依赖查找(Dependency Lookup)代码实现

依赖查找的主要问题是,这段代码必须依赖于JNDI环境,所以它不能在应用服务器之外运行,并且如果要用别的方式取代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 Injection)MyBusiness.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();

}

}

5.依赖拖拽(Dependency Pull)

最后需要介绍的是依赖拖拽,注入的对象如何与组件发生联系,这个过程就是通过依赖拖拽实现。

代码7 依赖拖拽示例


public static void main(String[] args) throws Exception{

//get the bean factory

BeanFactory factory = getBeanFactory();

MessageRender mr = (MessageRender) factory.getBean(“renderer”);

mr.render();

}

而通常对注入对象的配置可以通过一个xml文件完成。

使用这种方式对对象进行集中管理,使用依赖拖拽与依赖查找本质的区别是,依赖查找是在业务组件代码中进行的,而不是从一个集中的注册处,特定的地点执行

控制反转(Inversion of Control)与依赖注入(Dependency Injection),布布扣,bubuko.com

时间: 2024-10-09 01:12:22

控制反转(Inversion of Control)与依赖注入(Dependency Injection)的相关文章

Inversion of Control Containers and the Dependency Injection pattern(控制反转和依赖注入模式)

本文内容 Components and Services A Naive Example Inversion of Control Forms of Dependency Injection Constructor Injection with PicoContainer Setter Injection with Spring Interface Injection Using a Service Locator Using a Segregated Interface for the Loc

Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)

一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对 象无须关心持久层对象的具体实现,各层对象的调用完全面向接口.当系统需要重构时,代码的改写量将大大减少. 上面所说的一切都得宜于Spring的核心机制,依赖注入.依赖注入让bean与

控制反转(IoC)与依赖注入(DI)

前言 最近在学习Spring框架,它的核心就是IoC容器.要掌握Spring框架,就必须要理解控制反转的思想以及依赖注入的实现方式.下面,我们将围绕下面几个问题来探讨控制反转与依赖注入的关系以及在Spring中如何应用. 什么是控制反转? 什么是依赖注入? 它们之间有什么关系? 如何在Spring框架中应用依赖注入? 什么是控制反转 在讨论控制反转之前,我们先来看看软件系统中耦合的对象.图1:软件系统中耦合的对象从图中可以看到,软件中的对象就像齿轮一样,协同工作,但是互相耦合,一个零件不能正常工

解构控制反转(IoC)和依赖注入(DI)

1.控制反转 控制反转(Inversion of Control,IoC),简言之就是代码的控制器交由系统控制,而不是在代码内部,通过IoC,消除组件或者模块间的直接依赖,使得软件系统的开发更具柔性和扩展性.控制反转的典型应用体现在框架系统的设计上,是框架系统的基本特征,不管是.NET Framework抑或是Java Framework都是建立在控制反转的思想基础之上. 控制反转很多时候被看做是依赖倒置原则的一个同义词,其概念产生的背景大概来源于框架系统的设计,例如.NET Framework

Laravel 服务容器 IoC(控制反转) 和 DI(依赖注入)

Laravel 服务容器 IoC(控制反转) 和 DI(依赖注入) IoC 容器, laravel 的核心 Laravel 的核心就是一个 IoC 容器,根据文档,称其为“服务容器”,顾名思义,该容器提供了整个框架中需要的一系列服务.作为初学者,很多人会在这一个概念上犯难,因此,我打算从一些基础的内容开始讲解,通过理解面向对象开发中依赖的产生和解决方法,来逐渐揭开“依赖注入”的面纱,逐渐理解这一神奇的设计理念. 本文一大半内容都是通过举例来让读者去理解什么是 IoC(控制反转) 和 DI(依赖注

控制反转(IOC)和依赖注入(DI)的区别

IOC   inversion of control  控制反转 DI   Dependency Injection  依赖注入 要理解这两个概念,首先要搞清楚以下几个问题: 参与者都有谁? 依赖:谁依赖于谁?为什么需要依赖? 注入:谁注入于谁?到底注入什么? 控制反转:谁控制谁?控制什么?为何叫反转(有反转就应该有正转了)? 依赖注入和控制反转是同一概念吗? 下面就来简要的回答一下上述问题,把这些问题搞明白了,IoC/DI也就明白了.(1)参与者都有谁: 一般有三方参与者,一个是某个对象:一个

Java:控制反转(IoC)与依赖注入(DI)

01.紧耦合 在我们编码的过程中,通常都需要两个或者更多的类通过彼此的合作来实现业务逻辑,也就是说,某个对象需要获取与其合作对象的引用,如果这个获取的过程需要自己实现,代码的耦合度就会高,维护起来的成本就比较高. 我们来通过实战模拟一下.假如老王是少林寺的主持,他想让小二和尚去扫达摩院的地,代码可以这样实现. 小二类的代码如下所示: public class Xiaoer { public void saodi() { System.out.println("小二我在扫达摩院的地");

Spring3(一) 控制反转(IoC)和依赖注入(DI)

几个常用框架之间的关系 1       spring框架概述 1.1   什么是spring Spring是一个开源.轻量级的Java 开发框架.框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架.Spring的核心是控制反转(IoC)和面向切面(AOP). 轻量级指的是:与EJB对比,依赖资源少,销毁的资源少. 分层: 一站式,每一个层都提供了解决方案:但是又可以只选择其中一层 web层:struts,spring-MVC se

Spring核心思想:IOC(控制反转)、DI(依赖注入)和AOP(面向切面编程)

Spring有三大核心思想,分别是控制反转(IOC,Inversion Of Controller),依赖注入(DI,Dependency Injection)和面向切面编程(AOP,Aspect Oriented Programming). 控制反转(IOC,Inversion Of Controller) 控制反转不是什么技术,而是一种设计思想.在Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制. 传统正转 控制有反转,当然也就有原来的正转.正转就