Spring-IOC基础与原理

Spring的IOC(Inversion of Control,控制反转) 通过工厂模式加上反射机制来实现,这种设计模式允许开发者定义对象间的依赖关系,并由Spring容器在运行时自动注入这些依赖,而不是在代码中硬编码创建对象的过程。

控制反转(IoC) 就是把创建和管理 bean 的过程转移给了第三方,在Spring中就是 Spring IoC Container。对于 IoC 来说,最重要的就是容器,负责创建、配置和管理 bean,也就是它管理着 bean 的生命,控制着 bean 的依赖注入(DI)。IoC的核心思想是将对象的创建和管理交给容器,而不是由自己new出来,这样做的目的是为了降低耦合,提高代码的灵活性和可维护性。IoC是一种设计思想,而DI是实现这种思想的一种方式 ,通过依赖注入,容器负责将所需的依赖自动注入到对象中,而不需要对象自己去找。

Spring IoC容器主要有 BeanFactory和ApplicationContext 两个接口:

  • BeanFactory是基础容器,提供基本的依赖注入支持
  • ApplicationContext作为高级容器,扩展了更多功能,比如事件发布、国际化支持等。容器启动时,会读取配置文件(如XML)或注解,解析出Bean的定义,存储为BeanDefinition对象,然后通过反射机制实例化这些Bean,并管理它们的生命周期和依赖关系。

DI依赖注入的方式有多种,比如构造器注入、setter方法注入,或者通过注解如@Autowired自动注入。使用XML配置时,通过标签定义Bean,并指定其依赖。而在注解驱动的方式中,使用@Component等注解标记类,容器会自动扫描并注册这些Bean,然后通过@Autowired注入所需依赖。

总之:Spring IoC的核心在于通过容器管理对象的生命周期和依赖关系,实现控制反转,减少代码的耦合,提高可维护性和扩展性。

IOC容器

Spring IoC容器核心接口主要有 BeanFactory和 ApplicationContext:

  • BeanFactory:Spring 框架的基础设施,面向 Spring 本身,提供基本的依赖注入支持。
  • ApplicationContext:面向使用者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。

BeadFactory

Spring Bean的创建过程是典型的工厂模式。IOC容器为开发者管理对象间的依赖关系提供了很多便利和基础服务,在Spring中有许多的IOC容器的实现供用户选择和使用,BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范。

BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory,最终的默认实现类是 DefaultListableBeanFactory,实现现了所有接口:

  • ListableBeanFactory 接口:表示这些 Bean 是可列表的。
  • HierarchicalBeanFactory 接口:表示的是这些 Bean 是有继承关系的,也就是每个Bean 有可能有父 Bean。
  • AutowireCapableBeanFactory 接口:定义 Bean 的自动装配规则。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface BeanFactory {

//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&";

//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws BeansException;

//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
Object getBean(String name, Class requiredType) throws BeansException;

//提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);

//根据bean名字得到bean实例,并同时判断这个bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

//得到bean实例的Class类型
Class getType(String name) throws NoSuchBeanDefinitionException;

//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);
}

ApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface ApplicationContext extends
EnvironmentCapable,
ListableBeanFactory,
HierarchicalBeanFactory,
MessageSource,
ApplicationEventPublisher,
ResourcePatternResolver {
@Nullable
String getId();

String getApplicationName();

String getDisplayName();

long getStartupDate();

@Nullable
ApplicationContext getParent();

AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

ApplicationContext是Spring提供的一个高级IOC容器,它除了能够提供IOC容器的基本功能外,还为用户提供了以下的附加服务。从ApplicationContext接口的实现,我们看出其特点:

  • 支持信息源,可以实现国际化。(实现MessageSource接口)
  • 访问资源。(实现ResourcePatternResolver接口,这个后面要讲)
  • 支持应用事件。(实现ApplicationEventPublisher接口)

ApplicationContext定义的常用的实现类:

  • AnnotationConfigApplicationContext
  • ClassPathXmlApplicationContext
  • FileSystemXmlApplicationContext
1
2
3
4
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.ares");
context.register(IdGenApplication.class);
context.refresh();

Bean 生命周期

  • 配置解析: 在 Spring 容器启动时,首先会加载配置信息。这些配置可以是:

    • XML 配置文件
    • Java 注解(如 @Component, @Service 等)
    • Java Config(如使用 @Configuration 和 @Bean 的配置类)

    在这个阶段,Spring 会解析这些配置,提取出关于 Bean 的定义信息,如类名、作用域、依赖关系等。

  • Bean定义注册: 解析完成后,Spring 会将每个 Bean 的定义(BeanDefinition)注册到 BeanDefinitionRegistry 中。这个过程相当于将 Bean 的蓝图保存起来,供后续实例化使用。

  • Bean实例化: 当需要使用某个 Bean 时(比如通过 getBean() 调用,或被其他 Bean 依赖),Spring 会根据 BeanDefinition 实例化该 Bean。

    • 默认使用 无参构造函数 创建对象。
    • 支持使用工厂方法、构造函数注入等方式实例化。

    此时 Bean 只是一个空壳对象,属性尚未赋值。

  • 属性注入:Spring 会根据配置自动为 Bean 的属性赋值或注入依赖对象,包括:

    • 普通类型(String、int 等)
    • 其他 Bean(通过 @Autowired 或 XML 配置)
    • 集合、Map 等复杂结构
  • 初始化前处理(BeanPostProcessor.postProcessBeforeInitialization): 在正式初始化之前,如果存在实现了 BeanPostProcessor 接口的处理器,Spring 会调用其 postProcessBeforeInitialization() 方法。可用于对 Bean 进行包装、增强(如 AOP 动态代理)
    此时 Bean 已经完成属性注入,但还未执行初始化逻辑。

  • 初始化:这是 Bean 准备就绪的关键阶段,Spring 会按顺序执行以下操作:

    • 实现 InitializingBean 接口的 afterPropertiesSet() 方法
    • 执行自定义的 init-method(XML 中配置或注解指定)
  • 初始化后处理: 初始化完成后,Spring 再次调用 BeanPostProcessor 的 postProcessAfterInitialization() 方法。

    • 可以再次修改 Bean 实例
    • 常用于返回代理对象(AOP 就是基于此机制)
  • 销毁:当 Spring 容器关闭时(如调用 close() 或 shutdownHook 触发),Spring 会销毁所有单例 Bean。销毁流程如下:

    • 实现 DisposableBean 接口的 destroy() 方法
    • 执行自定义的 destroy-method(XML 中配置或注解指定)

    注意:只有单例作用域(Singleton) 的 Bean 才会被 Spring 主动管理生命周期。原型(Prototype)作用域的 Bean 不会被 Spring 管理销毁。

Bean实例化与初始化过程

在Spring Bean 的整个生命周期中可以归纳为三个大的阶段:

  • 容器启动阶段 - 配置解析与注册。容器的启动阶段就是注册Bean到BeanDefinationRegistry中的一个个BeanDefination了,这就是Spring为Bean实例化所做的预热的工作。
  • Bean实例化阶段 - Bean实例化与初始化
  • Bean销毁阶段

Bean的初始化有两种方式:

  • 懒加载:Spring只有在需要依赖对象的时候才开启相应对象的实例化阶段。
  • 非懒加载:容器启动阶段完成之后,将立即启动Bean实例化阶段。

Bean实例化与初始化步骤

Spring在启动阶段会通过BeanDefinationReader将配置元信息加载到内存生成相应的BeanDefination,然后注册到BeanDefinationRegistry中,BeanDefinationRegistry就是一个存放BeanDefination的容器,是一种键值对的形式存在,通过特定的Bean定义的id,映射到相应的BeanDefination。

BeanDefinitionRegistry有且仅有一个实现,那就是DefaultListableBeanFactory。BeanDefinitionRegistry接口有很多子类,比如经常用到的 AnnotationConfigApplicationContext,在实现时最终托管给DefaultListableBeanFactory进行处理的,所以真正实现这个接口的类是DefaultListableBeanFactory。

  • Bean实例化前操作
    在完成容器初始化阶段后,Bean都被托管到了DefaultListableBeanFactory,这个类中有个非常重要的字段:

    1
    private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

    beanPostProcessors 是一个BeanPostProcessor类型的集合。BeanPostProcessor是一个接口,其还有很多子接口,这些接口中提供了很多方法,对Spring Bean生命周期的不同阶段进行扩展,Bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的。

    在实现中会轮询 beanPostProcessors 列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么Spring自带的实例化bean的过程就被跳过了。

  • Bean实例化操作
    这个过程会通过反射来调用bean的构造器来创建bean的实例。具体需要使用哪个构造器,Spring为开发者提供了一个接口,允许开发者自己来判断用哪个构造器。这里会调用SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法,这个方法会返回候选的构造器列表,也可以返回空。可以自定义实现SmartInstantiationAwareBeanPostProcessor类,重写determineCandidateConstructors方法,指定构造器列表返回。

  • 合并后的BeanDefinition处理
    这里会调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition()方法。Spring会轮询BeanPostProcessor,依次调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition。第一个参数为beanDefinition,表示合并之后的RootBeanDefinition,可以在这个方法内部对合并之后的BeanDefinition进行再次处理。

MergedBeanDefinitionPostProcessor有2个实现类:

  • AutowiredAnnotationBeanPostProcessor:在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存。

  • CommonAnnotationBeanPostProcessor:在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存。

  • 实例化后阶段
    这里会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法,调用逻辑如下:
    postProcessAfterInstantiation方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过了。

  • 属性赋值前阶段
    这个阶段会调用 InstantiationAwareBeanPostProcessor 接口的 postProcessProperties 方法。如果InstantiationAwareBeanPostProcessor中的postProcessProperties和postProcessPropertyValues都返回空的时候,表示这个bean不需要设置属性,直接返回了,直接进入下一个阶段。PropertyValues中保存了bean实例对象中所有属性值的设置,所以可以在这个这个方法中对PropertyValues值进行修改。
    这个方法有2个比较重要的实现类:

    • AutowiredAnnotationBeanPostProcessor 在这个方法中对@Autowired、@Value标注的字段、方法注入值。
    • CommonAnnotationBeanPostProcessor 在这个方法中对@Resource标注的字段和方法注入值。
  • Bean属性赋值阶段
    循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中add方法设置的值。

  • Aware接口回调
    如果bean实例实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware等的接口,会按照下面的顺序依次进行调用:会依次调用这些接口。

  • Bean初始化前操作
    这里会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回null,当前方法将结束。通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。这个接口有2个实现类,比较重要:ApplicationContextAwareProcessor 和 CommonAnnotationBeanPostProcessor。 如果bean实现了下面的接口,在 ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中:

    • EnvironmentAware:注入Environment对象
    • EmbeddedValueResolverAware:注入EmbeddedValueResolver对象
    • ResourceLoaderAware:注入ResourceLoader对象
    • ApplicationEventPublisherAware:注入ApplicationEventPublisher对象
    • MessageSourceAware:注入MessageSource对象
    • ApplicationContextAware:注入ApplicationContext对象
    • CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法。
  • Bean初始化处理

    • 调用InitializingBean接口的afterPropertiesSet方法
    • 调用定义bean的时候指定的初始化方法。当bean实现了InitializingBean这个接口的时候,会在这个阶段调用afterPropertiesSet方法。
      调用顺序:InitializingBean中的afterPropertiesSet、然后再调用自定义的初始化方法。
  • Bean初始化后处理
    这里会调用BeanPostProcessor接口的postProcessAfterInitialization方法,返回null的时候,会中断上面的操作。通常称postProcessAfterInitialization这个方法为:bean初始化后置操作。

Bean 完整生命周期小结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
容器启动

├─ 加载配置 → 生成 BeanDefinition → 注册到 BeanDefinitionRegistry

└─ Bean实例化(触发时机:非懒加载或首次请求)

├─ 实例化前处理(自定义对象创建)
├─ 选择策略(构造方法/工厂方法/Supplier)
├─ 创建对象(反射/CGLIB)
├─ 处理循环依赖(三级缓存)
├─ 合并 BeanDefinition(缓存注入点)
├─ 属性填充(依赖注入)
├─ 初始化前处理(Aware 接口、@PostConstruct)
├─ Bean初始化处理(afterPropertiesSet)
└─ 初始化后处理(postProcessAfterInitialization)

├─ 销毁阶段

├─ 销毁前处理(@PreDestroy、 DisposableBean.destroy)
└─ 销毁

生命周期扩展点

阶段 可扩展点 接口/注解 描述
实例化前 postProcessBeforeInstantiation InstantiationAwareBeanPostProcessor 控制是否使用默认实例化流程
属性注入前 postProcessAfterInstantiation InstantiationAwareBeanPostProcessor 控制是否继续注入属性
属性注入时 postProcessProperties InstantiationAwareBeanPostProcessor 修改属性值
初始化前 postProcessBeforeInitialization BeanPostProcessor 初始化前处理(如代理、日志)
初始化 @PostConstruct, afterPropertiesSet, init-method 多种方式 自定义初始化逻辑
初始化后 postProcessAfterInitialization BeanPostProcessor 返回代理对象(如 AOP)
销毁 @PreDestroy, destroy, destroy-method 多种方式 清理资源

核心接口说明

  • BeanPostProcessor:是最核心的扩展接口之一,允许在 Bean 初始化前后插入自定义逻辑,常用于 AOP、日志、监控等功能。
1
2
3
4
5
6
7
8
9
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
  • InstantiationAwareBeanPostProcessor: 继承自 BeanPostProcessor,提供更细粒度的控制。可以在实例化前后、属性注入前后进行干预。
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}

default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
  • BeanFactoryPostProcessor: 不作用于 Bean 实例本身,而是作用于 ConfigurableListableBeanFactory。可以修改 BeanDefinition,比如动态添加、修改 Bean 的定义信息。
1
2
3
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
  • ApplicationListener / ApplicationEventPublisher: Spring 事件机制的核心接口。可监听容器启动、刷新、关闭等关键事件。
1
2
3
4
5
6
7
8
// 监听上下文刷新事件
@Component
public class MyContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("上下文已刷新");
}
}

Spring-IOC基础与原理
http://example.com/2025/06/11/spring-ioc基础与原理/
作者
ares
发布于
2025年6月11日
许可协议