【Spring】—IOC 的实现原理

前言

    提到Spring,不得不说Sping的两大核心概念:IOC 和 AOP ,现在来学习IOC 的实现原理。

正文

IOC 的提出

    软件系统各对象为了协同工作,依赖关系是无法避免的,为了实现对象之间或模块之间的解耦,软件专家Michael Mattson提出了IOC 理论,Sping 框架正是IOC 思想的应用。

IOC/DI 概念

    IOC(Inversion of Control) 控制反转,原来是由组件自身创建依赖,现在IOC 中将对象的创建权利交给了“第三方”,从而实现了具有依赖关系的对象之间的解耦,在Spring中则是将对象的生命周期交由Spring容器管理。
    某一场景下,对象A依赖于对象B,那么对象A在初始化或者运行到某一点时,必须自己主动去创建对象B或者使用已经创建的对象B,无论是创建还是使用,对于对象B的控制权都掌握在自己手上。
这里写图片描述
    当IOC容器加入之后,对象A和对象B之间失去了直接联系,当对象A运行到需要对象B时或者在这之前,IOC容器会主动创建了一个B对象注入到了对象A中,对象B的控制权交由了IOC容器,这便是“控制反转”的由来。
这里写图片描述
    DI(Dependency Injection)依赖注入,获得对象的过程由自身管理变成了由IOC容器主动注入,控制反转是什么方面的控制权利被反转了呢? 是获得对象的权利被反转了,在IOC容器运行期间,动态的将某种依赖关系注入到对象之中。

SpringIoc 原理

     反射+工厂模式
    反射
    根据给出的类名来动态的生成对象,这种编程方式让对象在生成时才决定到底是哪一种对象。
    工厂模式
    定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
    Spring容器(IOC容器)是一个对象制造工厂,当对象需要什么,工厂会创建并注入到对象中,对象的依赖关系写在配置文件中,当项目初始化时,会读取配置文件,根据反射机制将所需的对象创建出来。
下面来看下没有用反射时的工厂模式:

interface fruit{
    public abstract void eat();
} 
class Apple implements fruit{
     public void eat(){
         System.out.println("Apple");
     }
} 
class Orange implements fruit{
     public void eat(){
         System.out.println("Orange");
     }
}
//构造工厂类
//也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class Factory{
     public static fruit getInstance(String fruitName){
         fruit f=null;
         if("Apple".equals(fruitName)){
             f=new Apple();
         }
         if("Orange".equals(fruitName)){
             f=new Orange();
         }
         return f;
     }
}
class hello{
     public static void main(String[] a){
         fruit f=Factory.getInstance("Orange");
         f.eat();
     }
}

    可以看出,当添加了工厂模式之后,工厂模式负责创建对象,当想创建新的对象时,增加一个类去实现水果(fruit)类的接口,还要修改工厂类中的方法,这就违背了开放-封闭原则,为了解决这个问题,我们采用反射机制来实现工厂模式:

interface fruit{
     public abstract void eat();
}
class Apple implements fruit{
public void eat(){
         System.out.println("Apple");
     }
}
class Orange implements fruit{
public void eat(){
        System.out.println("Orange");
    }
}
class Factory{
    public static fruit getInstance(String ClassName){
        fruit f=null;
        try{
            // 反射应用
             f=(fruit)Class.forName(ClassName).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}
class hello{
    public static void main(String[] a){
        fruit f=Factory.getInstance("Reflect.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

     反射可以取得接口的实例而不用更改工厂类的代码,但是需要传入完整的包和类名,我们可以通过配置文件的方式将需要用到的实例记录上,通过读取配置文件中给出的类名生成相应的对象,IOC容器将所需的对象管理起来。

总结

     简单的介绍了下Spring IOC 的实现原理,当然Spring容器对对象的管理的过程更为复杂,后续再慢慢了解。

猜你喜欢

转载自blog.csdn.net/zt15732625878/article/details/81275998