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 | |
ApplicationContext
1 | |
ApplicationContext是Spring提供的一个高级IOC容器,它除了能够提供IOC容器的基本功能外,还为用户提供了以下的附加服务。从ApplicationContext接口的实现,我们看出其特点:
- 支持信息源,可以实现国际化。(实现MessageSource接口)
- 访问资源。(实现ResourcePatternResolver接口,这个后面要讲)
- 支持应用事件。(实现ApplicationEventPublisher接口)

ApplicationContext定义的常用的实现类:
- AnnotationConfigApplicationContext
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
1 | |
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 | |
生命周期扩展点
| 阶段 | 可扩展点 | 接口/注解 | 描述 |
|---|---|---|---|
| 实例化前 | postProcessBeforeInstantiation |
InstantiationAwareBeanPostProcessor |
控制是否使用默认实例化流程 |
| 属性注入前 | postProcessAfterInstantiation |
InstantiationAwareBeanPostProcessor |
控制是否继续注入属性 |
| 属性注入时 | postProcessProperties |
InstantiationAwareBeanPostProcessor |
修改属性值 |
| 初始化前 | postProcessBeforeInitialization |
BeanPostProcessor |
初始化前处理(如代理、日志) |
| 初始化 | @PostConstruct, afterPropertiesSet, init-method |
多种方式 | 自定义初始化逻辑 |
| 初始化后 | postProcessAfterInitialization |
BeanPostProcessor |
返回代理对象(如 AOP) |
| 销毁 | @PreDestroy, destroy, destroy-method |
多种方式 | 清理资源 |
核心接口说明
- BeanPostProcessor:是最核心的扩展接口之一,允许在 Bean 初始化前后插入自定义逻辑,常用于 AOP、日志、监控等功能。
1 | |
- InstantiationAwareBeanPostProcessor: 继承自 BeanPostProcessor,提供更细粒度的控制。可以在实例化前后、属性注入前后进行干预。
1 | |
- BeanFactoryPostProcessor: 不作用于 Bean 实例本身,而是作用于 ConfigurableListableBeanFactory。可以修改 BeanDefinition,比如动态添加、修改 Bean 的定义信息。
1 | |
- ApplicationListener / ApplicationEventPublisher: Spring 事件机制的核心接口。可监听容器启动、刷新、关闭等关键事件。
1 | |