`

什么是IOC

    博客分类:
  • JAVA
 
阅读更多
IoC(Inversion of Control)中文译为控制反转,目前Java社群中流行的各种轻量级容器的实现都是以IoC模式作为基础的。控制反转意味着在系统开发过程中,设计的类将交由容器去控制,而不是在类的内部去控制,类与类之间的关系将交由容器处理,一个类在需要调用另一个类时,只要调用另一个类在容器中注册的名字就可以得到这个类的实例,与传统的编程方式有了很大的不同,”不用你找,我来提供给你”,这就是控制反转的含义。



IoC是什么?Inversion of Control,即反转控制,或许说为依赖注入更为合适。IoC就是IoC,不是什么技术,与GoF一样,是一种设计模式。

    Interface Driven Design接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执 行:AInterface a = new AInterfaceImp(); 这样一来,耦合关系就产生了,如:
    Class A{
       AInterface a;
       A(){}
       aMethod(){
          a = new AInterfaceImp();
       }
    }
ClassA与AInterfaceImp就是依赖关系,如果想使用AInterface的另外一个实现就需要更改代码了。当然我们可以建立一个Factory来根据条件生成想要的AInterface的具体实现,即:
    InterfaceImplFactory{
        AInterface create(Object condition){
            if(condition = condA){
                return new AInterfaceImpA();
            }elseif(condition = condB){
                return new AInterfaceImpB();
            }else{
                return new AInterfaceImp();
            }
        }
    }
表 面上是在一定程度上缓解了以上问题,但实质上这种代码耦合并没有改变。通过IoC模式可以彻底解决这种耦合,它把耦合从代码中移出去,放到统一的XML文 件中,通过一个容器在需要的时候把这个依赖关系形成,即把需要的接口实现注入到需要它的类中,这可能就是“依赖注入”说法的来源了。
    IOC模式,系统中通过引入实现了IOC模式的IOC容器,即可由IOC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实 际的应用程序代码分开。其中一个特点就是通过文本的配件文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。
    当前比较知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等。
    在上面的几个IOC容器中,轻量级的有Pico Container、Avalon、Spring、HiveMind等,超重量级的有EJB,而半轻半重的有容器有JBoss,Jdon等。
    可以把IoC模式看做是工厂模式的升华,可以把IoC看作是一个大工厂,只不过这个大工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java 的“反射”编程,根据XML中给出的类名生成相应的对象。从实现来看,IoC是把以前在工厂方法里写死的对象生成代码,改变为由XML文件来定义,也就是 把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。
    IoC中最基本的Java技术就是“反射”编程。反射又是一个生涩的名词,通俗的说反射就是根据给出的类名(字符串)来生成对象。这种编程方式可以让对象 在生成时才决定要生成哪一种对象。反射的应用是很广泛的,象Hibernate、String中都是用“反射”做为最基本的技术手段。
    在过去,反射编程方式相对于正常的对象生成方式要慢10几倍,这也许也是当时为什么反射技术没有普通应用开来的原因。但经SUN改良优化后,反射方式生成对象和通常对象生成方式,速度已经相差不大了(但依然有一倍以上的差距)。
    IoC最大的好处是什么?因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是现实于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拨(有点象USB接口和SCIS硬盘了)。
    IoC最大的缺点是什么?(1)生成一个对象的步骤变复杂了(其实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。(2)对象 生成因为是使用反射编程,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。(3) 缺少IDE重构操作的支持,如果在Eclipse要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有XML方式的缺憾所在。
IOC实现初探
   IOC关注服务(或应用程序部件)是如何定义的以及他们应该如何定位他们依赖的其它服务。通常,通过一个容器或定位框架来获得定义和定位的分离,容器或定位框架负责:


保存可用服务的集合
提供一种方式将各种部件与它们依赖的服务绑定在一起
为应用程序代码提供一种方式来请求已配置的对象(例如,一个所有依赖都满足的对象), 这种方式可以确保该对象需要的所有相关的服务都可用。
现有的框架实际上使用以下三种基本技术的框架执行服务和部件间的绑定:


类型1 (基于接口): 可服务的对象需要实现一个专门的接口,该接口提供了一个对象,可以从用这个对象查找依赖(其它服务)。早期的容器Excalibur使用这种模式。
类型2 (基于setter): 通过JavaBean的属性(setter方法)为可服务对象指定服务。HiveMind和Spring采用这种方式。
类型3 (基于构造函数): 通过构造函数的参数为可服务对象指定服务。PicoContainer只使用这种方式。HiveMind和Spring也使用这种方式。
====================================================================================

IoC就是Inversion of Control,控制反转。在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。


下面我们以几个例子来说明什么是IoC


假设我们要设计一个Girl和一个Boy类,其中Girl有kiss方法,即Girl想要Kiss一个Boy。那么,我们的问题是,Girl如何能够认识这个Boy?


在我们中国,常见的MM与GG的认识方式有以下几种
1 青梅竹马; 2 亲友介绍; 3 父母包办
那么哪一种才是最好呢?


青梅竹马:Girl从小就知道自己的Boy。


public class Girl {
void kiss(){
Boy boy = new Boy();
}
}


然而从开始就创建的Boy缺点就是无法在更换。并且要负责Boy的整个生命周期。如果我们的Girl想要换一个怎么办?(严重不支持Girl经常更换Boy,#_#)


亲友介绍:由中间人负责提供Boy来见面


public class Girl {
void kiss(){
Boy boy = BoyFactory.createBoy();
}
}


亲友介绍,固然是好。如果不满意,尽管另外换一个好了。但是,亲友BoyFactory经常是以Singleton的形式出现,不然就是,存在于 Globals,无处不在,无处不能。实在是太繁琐了一点,不够灵活。我为什么一定要这个亲友掺和进来呢?为什么一定要付给她介绍费呢?万一最好的朋友爱 上了我的男朋友呢?


父母包办:一切交给父母,自己不用费吹灰之力,只需要等着Kiss就好了。


public class Girl {
void kiss(Boy boy){
// kiss boy
boy.kiss();
}
}


Well,这是对Girl最好的方法,只要想办法贿赂了Girl的父母,并把Boy交给他。那么我们就可以轻松的和Girl来Kiss了。看来几千年传统的父母之命还真是有用哦。至少Boy和Girl不用自己瞎忙乎了。


这就是IOC,将对象的创建和获取提取到外部。由外部容器提供需要的组件。


我们知道好莱坞原则:“Do not call us, we will call you.” 意思就是,You, girlie, do not call the boy. We will feed you a boy。


我们还应该知道依赖倒转原则即 Dependence Inversion Princinple,DIP


Eric Gamma说,要面向抽象编程。面向接口编程是面向对象的核心。


组件应该分为两部分,即 Service, 所提供功能的声明 Implementation, Service的实现


好处是:多实现可以任意切换,防止 “everything depends on everything” 问题.即具体依赖于具体。


所以,我们的Boy应该是实现Kissable接口。这样一旦Girl不想kiss可恶的Boy的话,还可以kiss可爱的kitten和慈祥的grandmother。
二、IOC的type


IoC的Type指的是Girl得到Boy的几种不同方式。我们逐一来说明。


IOC type 0:不用IOC
public class Girl implements Servicable {
private Kissable kissable;
public Girl() {
kissable = new Boy();
}
public void kissYourKissable() {
kissable.kiss();
}
}

Girl自己建立自己的Boy,很难更换,很难共享给别人,只能单独使用,并负责完全的生命周期。


IOC type 1,先看代码:代码


public class Girl implements Servicable {

Kissable kissable;

public void service(ServiceManager mgr) {
kissable = (Kissable) mgr.lookup(“kissable”);
}

public void kissYourKissable() {
kissable.kiss();
}

}


这种情况出现于Avalon Framework。一个组件实现了Servicable接口,就必须实现service方法,并传入一个ServiceManager。其中会含有需要的其它组件。只需要在service方法中初始化需要的Boy。


另外,J2EE中从Context取得对象也属于type 1。它依赖于配置文件。


IOC type 2:


public class Girl {

private Kissable kissable;

public void setKissable(Kissable kissable) {
this.kissable = kissable;
}

public void kissYourKissable() {
kissable.kiss();
}

}


Type 2出现于Spring Framework,是通过JavaBean的set方法来将需要的Boy传递给Girl。它必须依赖于配置文件。

IOC type 3:


public class Girl {

private Kissable kissable;

public Girl(Kissable kissable) {
this.kissable = kissable;
}

public void kissYourKissable() {
kissable.kiss();
}

}


这就是PicoContainer的组件 。通过构造函数传递Boy给Girl

PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy.class);
container.registerComponentImplementation(Girl.class);
Girl girl = (Girl) container.getComponentInstance(Girl.class);
girl.kissYourKissable();
分享到:
评论

相关推荐

    什么是Ioc和DI

    什么是Ioc和DI

    IOC详解IOC详解IOC详解IOC详解

    IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解

    IoC对象实例IoC对象实例

    IoC对象实例IoC对象实例IoC对象实例

    Spring中IoC优点与缺点解析

    主要为大家详细解析了Spring中IoC优点与缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    IOC模式 c#经典例子

    IOC模式 c#经典例子 IOC 例子 IOC模式 c#经典例子 IOC 例子 IOC模式 c#经典例子 IOC 例子

    Spring笔记(面试题)md

    3.什么是IOC 4.基于xml的IOC 5.项目案例 6.基于注解的IOC 7.添加包扫描的方式 8.为应用指定多个 Spring 配置文件 9.spring配置文件的整合 10.面向切面编程AOP 11.手写AOP框架 12.Spring支持的AOP的实现 13.AOP常用...

    springIoc实现原理

    spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合

    精通Spring4.x企业应用开发实战

    个人印象比较深刻是在讲解IOC的时候举了一个《墨攻》例子,通过导演和演员的关系很巧妙地说明了什么是IOC,为什么要IOC。虽然Spring已经更新到5点几了,但是通过精读这本书,对于一名实习生,也够应对面试了。

    Spring源码解析4章150页+Spring3.2.4中文注释源码

    1、什么是IOC/DI 2、SpringIOC体系结构 3、源码分析-IOC容器的初始化 4、源码分析-IOC容器的依赖注入 5、源码分析-IOC容器的高级特性 三阶段 Spring AOP的涉及原理及具体实践 SpringJDBC的涉及原理及二次开发 ...

    SpringFramework常见知识点.md

    - 什么是IOC容器和DI依赖注入? - Spring依赖注入的方式有几种? - 一个bean的定义包含了什么?(BeanDefinition) - bean的作用域有哪些? - Spring 的扩展点主要有哪些? - Spring如何解决循环依赖? - 事务的传播...

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 <!-- 配置数据源 --> destroy-method="close"> <value>org.gjt.mm.mysql.Driver <value>jdbc:mysql://localhost:3306/demo <value>root ...

    SpringIoC的简单实现

    我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个...

    go-simple-ioc:Golang 的简单 IoC 容器

    什么是IoC? 控制反转(IoC)是一种编程原理,用于反转控制以实现松散耦合。 控件是指类具有的任何附加职责,例如应用程序的流程或对对象创建或依赖对象创建和绑定流程的控制(请参阅教程)。 顾名思义,IoC 反转...

    CH02-IOC依赖注入.pptx

    理解什么是IoC和DI。 理解构造注入 理解不同数据类型的注入方法 掌握p命名空间注入 Bean自动装配

    SpringIoc示例代码

    SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码

    spring ioc.jar

    spring ioc.jar springioc必备开发工具包

    Spring通过注解实现IOC

    Spring通过注解实现IOC,Spring通过注解实现IOC,Spring通过注解实现IOC

    以注解方式模拟Spring IoC AOP

    以注解方式模拟Spring IoC AOP,了解Spring是如何实现的.

    SpringIOC原理实现

    以excel导入为例子,看看springIoc是什么原理,如何自己写一个

    spring ioc aop 源码阅读pdf

    这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,...

Global site tag (gtag.js) - Google Analytics