IOC思想

IOC:控制反转

IOC是Spring的核心,贯穿始终

对于Spring框架来说,就是由spring IOC容器来负责控制对象的生命周期和对象间的关系

1.在传统开发模式下,我们是采用直接new一个对象的方式来创建对象,也就是所依赖的对象由自己控制

但是这种可以交给IOC容器来控制对象

2.控制的是对象

3.有了IOC之后,所依赖的对象直接由Ioc容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变为被动接受,故称之为反转

4.所依赖的对象的获取  被反转

Spring所倡导的开发方式:即所有的类都会在spring容器中登记,告诉spring 你是什么对象,你需要什么对象

之后spring会在系统运行到适当的时候,把你要的对象给你,同时也把你交给其他需要你这个对象的对象。所有类的创建和销毁都是由spring来控制的,也就是说控制对象生存周期的不再是引用它的对象,而是spring。

对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转

IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现。比如对象A需要操作数据库,之前我们总是要在A中自己编写代码来获得Connection对象,自从有了spring之后,就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A对象不需要知道。在系统运行中,spring会在适当的时候制造一个Connection,就像打针一样,将其注射到A中,这样就完成了对各个对象之间关系的控制。A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的

Spring的IOC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段

1.容器启动阶段

2.Bean实例化阶段

Spring的IoC容器在实现控制反转和依赖注入功能的时候不是一蹴而就的,也分了两个阶段,并且大致对两个阶段所做的事情有一个印象

容器启动阶段的讲解

1.IOC的技术实现方式

“伙计,来杯啤酒!”当你来到酒吧,想要喝杯啤酒的时候,通常会直接招呼服务生,让他为你送来一杯清凉解渴的啤酒。同样地,作为被注入对象,要想让IoC容器为其提供服务,并将所需要的被依赖对象送过来,也需要通过某种方式通知对方。

  • 如果你是酒吧的常客,或许你刚坐好,服务生已经将你最常喝的啤酒放到了你面前如果你是初次或偶尔光顾
  • 也许你坐下之后还要招呼服务生,“Waiter,Tsingdao, please.”
  • 还有一种可能,你根本就不知道哪个牌子是哪个牌子,这时,你只能打手势或干脆画出商标图来告诉服务生你到底想要什么了吧!

不管怎样,你终究会找到一种方式来向服务生表达你的需求,以便他为你提供适当的服务。那么,在IoC模式中,被注入对象又是通过哪些方式来通知IoC容器为其提供适当服务的呢?

常用的有两种方式:构造方法注入和setter方法注入,还有一种已经退出历史舞台的接口注入方式,下面就比较一下三种注入方式:

  • 接口注入。从注入方式的使用上来说,接口注入是现在不甚提倡的一种方式,基本处于“退役状态”。因为它强制被注入对象实现不必要的接口,带有侵入性。而构造方法注入和setter方法注入则不需要如此。
  • 构造方法注入。这种注入方式的优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用。缺点就是,当依赖对象比较多的时候,构造方法的参数列表会比较长。而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。而且在Java中,构造方法无法被继承,无法设置默认值。对于非必须的依赖处理,可能需要引入多个构造方法,而参数数量的变动可能造成维护上的不便。
  • setter方法注入。因为方法可以命名,所以setter方法注入在描述性上要比构造方法注入好一些。 另外,setter方法可以被继承,允许设置默认值,而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。其实,这些操作都是由IoC容器来做的,我们所要做的,就是调用IoC容器来获得对象而已

IOC容器为被注入对象提供被依赖对象的方式有:构造方法注入,setter注入,接口注入

构造器注入

构造器注入,顾名思义就是被注入的对象通过在其构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。

YoungMan(BeautifulGirl beautifulGirl){
        this.beautifulGirl = beautifulGirl;
}

构造器注入方式比较直观,对象构造完毕后就可以直接使用,这就好比你出生你家里就给你指定了你媳妇

setter 方法注入

对于 JavaBean 对象而言,我们一般都是通过 getter 和 setter 方法来访问和设置对象的属性。所以,当前对象只需要为其所依赖的对象提供相对应的 setter 方法,就可以通过该方法将相应的依赖对象设置到被注入对象中。如下:

public class YoungMan {
    private BeautifulGirl beautifulGirl;

    public void setBeautifulGirl(BeautifulGirl beautifulGirl) {
        this.beautifulGirl = beautifulGirl;
    }
}

相比于构造器注入,setter 方式注入会显得比较宽松灵活些,它可以在任何时候进行注入(当然是在使用依赖对象之前),这就好比你可以先把自己想要的妹子想好了,然后再跟婚介公司打招呼,你可以要林志玲款式的,赵丽颖款式的,甚至凤姐哪款的,随意性较强。

接口方式注入

接口方式注入显得比较霸道,因为它需要被依赖的对象实现不必要的接口,带有侵入性。一般都不推荐这种方式

 

2.IoC容器及IoC容器如何获取对象间的依赖关系

Spring中提供了两种IOC容器

  • BeanFactory
  • ApplicationContext

ApplicationContext是BeanFactory的子类,所以,ApplicationContext可以看做更强大的BeanFactory,他们两个之间的区别如下

  • BeanFactory,基础类型IOC容器,提供完整的IOC服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象要访问容器中某个收官对象的时候,才对该收官对象进行初始化以及依赖注入操作。所以相对来说,容器启动初期速度较快,所需要的资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IOC容器
  • ApplicationContext。ApplicationContext在BeanFactory的基础上创建,是相对比较高级的容器实现,除了拥有BeanFactoy的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布,国际化信息支持等,Applicationontext所管理的对象,在该容器启动成功之后,默认全部初始化并绑定完成。所以,相对于BeanFactory,ApplicationContext要求更多的资源,同时,因为在启动时就完成所有初始化,容器启动时间也会较长一些。在那些系统资源充足,并要求更多功能的场合中,ApplicationContext类型的容器是比较合适的选择

无论使用哪种容器,都需要以某种方法告诉容器关于对象依赖的信息。只有这样容器才能合理的创造出对象,否则spring也不知道哪个对象依赖哪个对象,如果胡乱注入,那不是创造出了四不像。使用spring提供的方法

  • 通过最基本的文本文件来记录被注入对象和其依赖对象之间的对应关系
  • 通过描述性较强的XML文件格式来记录对应信息
  • 通过编写代码的方式来注册这些对应的信息
  • 通过注解的方式来注册这些对应的信息

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值