Spring的IOC容器

271 阅读4分钟

一、什么是IOC

IOC翻译为控制反转。

控制反转是一种软件设计原则,它将应用程序的控制权从应用程序代码中分离出来,并交给一个容器来管理。

传统的编码方式中,对象间的依赖关系是通过对象自身直接创建和管理的。而在控制反转中,对象的创建和管理被委托给一个容器,对象之间的依赖关系也由容器来维护和注入。

控制反转的一个重要思想是依赖注入(Dependency Injection),它通过将对象的依赖关系通过构造函数、属性或者接口注入的方式来实现。通过控制反转和依赖注入,我们能够实现松耦合、可测试、可维护的应用程序。

二、IOC容器的作用和特点

IoC 容器是 Spring Framework 中的一个关键组件,它的主要作用是创建和管理应用程序中的对象。具体而言,IoC 容器负责实例化对象、解决对象之间的依赖关系,并负责销毁对象。

IoC 容器的特点如下:

  • 创建和管理对象;
  • 处理对象之间的依赖关系;
  • 管理对象的生命周期;
  • 松耦合应用程序;

2.1 对象的创建和管理

IoC 容器负责创建应用程序中的对象,并将其托管起来。我们可以通过配置文件或者注解的方式告诉容器需要创建哪些对象,容器会根据配置信息进行实例化。

2.2对象的依赖解决

IoC 容器负责解决对象之间的依赖关系。如果一个对象 A 依赖于另一个对象 B,那么容器会在创建对象 A 时将对象 B 自动注入到对象 A 中。这样,对象 A 就可以直接使用对象 B,而不需要关心对象 B 的创建和管理逻辑。

2.3生命周期管理

IoC 容器负责对象的生命周期管理。容器可以管理对象的创建、初始化、使用和销毁过程。我们可以通过配置和扩展容器的回调接口来实现自定义的生命周期管理操作。

2.4 松耦合的应用程序

通过使用 IoC 容器,我们可以将对象的依赖关系从应用程序代码中分离出来,从而实现松耦合的应用程序。对象之间不再直接依赖于具体的实现类,而是依赖于接口或者抽象类。这样,我们可以方便地替换具体的实现类,而不需要修改大量的代码。

三、Spring IOC容器的实现原理

Spring IOC(Inversion of Control,控制反转)的实现原理主要依赖于工厂模式和反射机制。

  1. 工厂模式:Spring 使用了工厂模式来创建 bean 实例。这是通过 BeanFactory 接口实现的。BeanFactory 在加载 bean 配置文件时,读取用户定义的配置信息,在创建 bean 时,对 bean 进行必要的初始化,并对 bean 的依赖关系进行注入。
  2. 反射机制:Spring 使用 Java 反射机制创建 bean 实例。在 Spring 的配置文件中,用户通常指定 bean 的类名,然后 Spring 通过反射机制,动态创建 bean 的实例。

简单的实现示例:

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class SpringIoCExample {
    public static void main(String[] args) {
        // 初始化 Spring 容器
        AbstractXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
 
        // 获取 bean 对象
        MyBean myBean = (MyBean) context.getBean("myBean");
 
        // 使用 bean
        myBean.doSomething();
 
        // 关闭 Spring 容器
        context.close();
    }
}
 
class MyBean {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

在这个例子中,ClassPathXmlApplicationContext 负责读取 spring-config.xml 配置文件,并通过反射机制创建 myBean 实例。myBean 是用户定义的一个简单的 bean 类,它有一个 doSomething() 方法。

四、对IOC容器的思考和应用

问题:Spring中IOC容器使用什么数据结构来存储对象

猜测的时候,我们可以这样思考。Spring的IOC容器管理的对象应该都是单例的,唯一的。那么应该是使用的HashMap或者HashSet这一类的数据结构。但是HashSet取值的时候,需要每次都遍历,这样效率肯定是低下的。那么大概率是HashMap

问题:如何获取Spring的IOC容器

方式一:实现ApplicationContextAware

@Compoent
public class ApplicationContextUtilsA implements ApplicationContextAware{

    private static ApplicationContext context;
    
    public void setApplicationContext(ApplicationContext applicationContesxt) throws BeansException {
    
        if (Objects.isNull(context)){
            context = applicationContext;
        }
    }
    
    public statis getContext(){
        return context;
    }

}

方式二:配置Spring监听

@Compoent
public class ApplicationContextUtilsB implements ApplicationListener<ContextRefreshedEvent>{

    private static ApplicationContext context;
    
    public void onApplicationEvent(ContextRefreshedEvent event) throws BeansException {
    
        if (Objects.isNull(context)){
            context = event.getApplicationContext();
        }
    }
    
    public statis getContext(){
        return context;
    }

}

为什么我们需要获取IOC容器呢?

在我们的项目工程当中,并不是所有的对象都是交给Spring管理的。当想在非Spring管理的对象当中使用IOC容器中的对象。那么就需要获取IOC容器