IoC 容器体系

IoC 容器是 Spring 的核心模块,是抽象了对象管理、依赖关系管理的框架解决方案。Spring 提供给了很多容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器必须遵从一定的原则。

BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器必须遵从一定的原则。

ApplicationContext 继承 BeanFactory 的子接口,还继承了 ResourcesLoader、MessageSource 等接口,因此其提供的功能更加丰富。


什么是 IoC(控制反转)?

IoC(Inversion of Control,控制反转)是一种设计原则,指的是将对象的控制权从程序中转移到外部容器或框架中。

IoC 使得类的依赖关系从硬编码转化为动态注入,从而增强了系统的可扩展性、可维护性以及解耦性。

在 IoC 中,控制反转的核心思想是:系统中不再由应用程序显式地创建对象,而是通过容器来创建和管理对象。容器负责控制对象的生命周期,并在需要时为对象提供依赖。


IoC 容器的作用

IoC 容器的主要功能是:

  • 对象创建:容器负责实例化对象而不需要显式代码
  • 依赖注入:容器将一个对象的依赖关系自动注入到该对象中
  • 生命周期管理:容器控制对象的创建、销毁和管理
  • 解耦:对象之间的依赖关系通过容器管理

IoC 容器的工作原理

IoC 容器主要依赖于依赖注入(DI)机制来实现控制反转。依赖注入有三种常见方式:

  1. 构造函数注入:通过构造函数将依赖的对象传递给目标对象
  2. Setter 注入:通过提供 setter 方法将依赖注入到目标对象
  3. 接口注入:目标对象实现某个接口,容器通过该接口提供依赖关系

IoC 容器的核心功能

  • 对象的注册:容器通过配置文件或代码注册不同类型的对象
  • 依赖注入:容器通过配置或者注解将对象所依赖的其它对象自动注入
  • 生命周期管理:容器控制对象的生命周期,如单例模式、原型模式等
  • 作用域管理:容器支持不同作用域的对象
  • 事件管理:容器支持事件驱动的机制

IoC 容器的优点

  • 解耦:通过 IoC 容器,系统中的各个组件不再直接依赖于彼此
  • 可扩展性:依赖关系是由容器动态管理的
  • 可维护性:IoC 容器管理对象的生命周期和依赖关系
  • 模块化:通过容器管理对象,使得不同模块间的隔离性增强
  • 测试友好:IoC 容器使得单元测试变得更加容易

Bean 生命周期

编写代码

WzkBean

package wzk.bean;

import org.springframework.beans.factory.InitializingBean;

public class WzkBean implements InitializingBean {

    public WzkBean() {
        System.out.println("WzkBean 构造方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("WzkBean afterPropertiesSet");
    }
}

WzkBeanPostProcessor

package wzk.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class WzkBeanPostProcessor implements BeanPostProcessor {

    public WzkBeanPostProcessor() {
        System.out.println("WzkBeanPostProcessor 构造方法");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("WzkBeanPostProcessor postProcessBeforeInitialization");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("WzkBeanPostProcessor postProcessAfterInitialization");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

WzkBeanFactoryPostProcessor

package wzk.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class WzkBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public WzkBeanFactoryPostProcessor() {
        System.out.println("WzkBeanFactoryPostProcessor 构造方法");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("WzkBeanFactoryPostProcessor postProcessBeanFactory");
    }
}

配置 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
">
    <bean id="wzkBean" class="wzk.bean.WzkBean"></bean>
    <bean id="wzkBeanPostProcessor" class="wzk.bean.WzkBeanPostProcessor"></bean>
    <bean id="wzkBeanFactoryPostProcessor" class="wzk.bean.WzkBeanFactoryPostProcessor"></bean>
</beans>

测试代码

public class WzkIocTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        WzkBean wzkBean = (WzkBean) context.getBean("wzkBean");
        System.out.println(wzkBean);
    }
}

运行结果

WzkBeanFactoryPostProcessor 构造方法
WzkBeanFactoryPostProcessor postProcessBeanFactory
WzkBeanPostProcessor 构造方法
WzkBean 构造方法
WzkBeanPostProcessor postProcessBeforeInitialization
WzkBean afterPropertiesSet
WzkBeanPostProcessor postProcessAfterInitialization
wzk.bean.WzkBean@40005471