spring.main.lazy-initialization 配置的实现机制:
Spring Boot 中 spring.main.lazy-initialization 配置的实现机制
当在 Spring Boot 应用中配置 spring.main.lazy-initialization=true 时,整个懒加载的机制是通过以下类和流程实现的:
1. 核心实现类:LazyInitializationBeanFactoryPostProcessor
LazyInitializationBeanFactoryPostProcessor 是实现全局懒加载的核心类。这个类位于 org.springframework.boot 包下,是一个 BeanFactoryPostProcessor 实现。
2. 工作原理
配置阶段:
- 当在
application.properties或application.yml中设置spring.main.lazy-initialization=true后,SpringApplication实例的lazyInitialization属性会被设置为true。
注册阶段:
- 在
SpringApplication.run()方法中,会调用prepareContext()方法 - 当
this.lazyInitialization为true时,Spring 会向容器注册一个LazyInitializationBeanFactoryPostProcessor的实例
执行阶段:
- 在 Spring 容器的
refresh()方法中,会调用所有BeanFactoryPostProcessor的postProcessBeanFactory()方法 LazyInitializationBeanFactoryPostProcessor的postProcessBeanFactory()方法会遍历容器中的所有BeanDefinition
3. 关键代码逻辑
java
public final class LazyInitializationBeanFactoryPostProcessor
implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// 遍历所有Bean定义
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 排除特定类型的Bean(如基础设施Bean)
if (!isExcluded(beanDefinition, beanName)) {
// 关键代码:将BeanDefinition的lazyInit属性设置为true
beanDefinition.setLazyInit(true);
}
}
}
// 检查是否应该排除该Bean(如SmartInitializingSingleton类型等)
private boolean isExcluded(BeanDefinition beanDefinition, String beanName) {
// 实现排除逻辑
}
}
4. 排除条件
根据搜索结果,LazyInitializationBeanFactoryPostProcessor 会排除以下类型的 Bean:
- 基础设施角色 Bean:自动从懒加载中排除
- SmartInitializingSingleton 类型:这类 Bean 需要立即初始化
- 已经显式设置
lazy-init属性的 Bean:如果已经明确设置了值,则不覆盖
5. 使用方式
配置文件方式:
properties
# application.properties
spring.main.lazy-initialization=true
编程方式:
java
// 使用 SpringApplicationBuilder
new SpringApplicationBuilder(MyApplication.class)
.lazyInitialization(true)
.run(args);
// 使用 SpringApplication
SpringApplication app = new SpringApplication(MyApplication.class);
app.setLazyInitialization(true);
app.run(args);
6. 生效时机
- 这个处理器会在 Spring 容器的
refresh()方法中被调用 - 具体是在调用
finishBeanFactoryInitialization()创建所有单例对象之前执行 - 这样设置后,在
finishBeanFactoryInitialization()中这些 Bean 将不会被立即创建,从而实现了全局懒加载
7. 注意事项
- 启动性能提升:懒加载可以显著减少应用启动时间,因为大部分 Bean 直到真正使用时才创建
- 内存占用减少:Spring Boot 3.4 的懒加载特性可以让内存占用减少 80%
- 潜在问题:所有 Bean 都延迟初始化可能导致某些依赖关系问题,需要谨慎使用
总结
spring.main.lazy-initialization=true 配置的核心实现类是 LazyInitializationBeanFactoryPostProcessor 。这个 BeanFactoryPostProcessor 会在 Spring 容器刷新时遍历所有 BeanDefinition,并将那些没有被排除的 Bean 的 lazyInit 属性设置为 true,从而实现了全局的延迟初始化效果。