IoC(Inverse of Control)控制反转,是Spring的两大特点之一

IoC通过两种方式实现:依赖查找(DL)和依赖注入(DI)

DL已经被抛弃,因为他需要用户自己去使用API进行查找资源和组装对象。即有侵入性,与Spring的无侵入性相违背

DI是Spring目前使用的方式,容器负责组件的装配。Spring支持的构造函数注入和属性注入。

构造注入

通过一个旧的例子来说明构造注入,墨攻中,刘德华饰演墨者革离,守军询问他是谁,他回答"墨者革离"

public class MoAttack{//编写一个剧本成员
    
    private GeLi geli;//设置一个角色革离
    
    public MoAttack(GeLi geli){//在构造函数进行注入,该成员为革离
        this.geli = geli;
    }

    public void cityGateAsk(){//回答守军
        geli.responAsk("墨者革离");
    }
}
public class Director{
    public void direct(){
        
        Geli geli = new LiuDeHua();//实例化一个Geli对象

        MoAttack moAttack = new MoAttack(geli);//通过构造函数注入

        moAttack.cityGateAsk();//结果返回的是墨者革离,而非刘德华
    }
}

从上面的例子我们可以看出来,当守军问"来者何人"的时候,无论他是刘德华,还是张德华,只要是饰演革离的人都是回答"墨者革离",但是很重要的一个问题,主角是不是每次都会出场,如果不是我们应该怎么做?

属性注入

public class MoAttack{//编写一个剧本成员
    
    private GeLi geli;//设置一个角色革离
    
    public void setGeli(GeLi geli){//通过set方法,属性注入,当需要革离的时候才分配革离的演员
        this.geli= geli;
    }

    public void cityGateAsk(){//回答守军
        geli.responAsk("墨者革离");
    }
}
public class Director{
    public void direct(){
        
        Geli geli = new LiuDeHua();//实例化一个Geli对象
        MoAttack moAttack = new MoAttack();//通过构造函数创建一个剧本成员

        moAttack.setGeli(geli);//通过属性setter注入依赖,安排革离演员

        moAttack.cityGateAsk();//结果返回的是墨者革离,而非刘德华
    }
}

通过属性注入的方式,我们可以避免每一次构建MoAttack都需要注入一个GeLi对象。这样就可在不同的场景通过setter注入不同的角色

对于IoC来说,最重要的就是容器。容器管理者Bean的生命周期。

Spring设计了两类容器

  1. BeanFactory,Spring的基础设施,面向Spring。只提供注册(put),获取(get)两个功能。
  2. ApplicationContext,面向Spring框架的开发者。

spring 每天晚上12点10执行_ci

图片转载自

上述是较为完整的ApplicationContext类继承体系

ClassPathXmlApplicationContext的大概构造过程为

  1. 用户构造ClassPathXmlApplicationContext
  2. ClassPathXmlApplicationContext首先访问高级容器中的refresh方法,这个是个模板方法,需要回调子类(低级容器)的refreshBeanFactory方法,这个方法的作用是使用低级容器加载所有BeanDefinition和Properties到容器中
  3. 低级容器加载成功后,高级容器开始处理一些回调。(功能越来越多,越来越迷茫)

总结

BeanFacotory的IoC只需要两个步骤:

  1. 加载配置文件,解析成BeanDefinition放在Map里
  2. 调用getBean的时候,从BeanDefinition所属的Map里,拿出Class对象进行实例化,同时,如果有依赖关系,将递归调用getBean方法-完成依赖注入

Application包含低级容器的功能,当他执行refreesh模板方法的时候,将刷新整个容器的Bean,同时作为高级容器,包含太多的功能,一句话,它不仅仅是Ioc。他支持不同信息源头,支持 BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等。