spring.main.lazy-initialization配置的实现机制

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:

  1. 基础设施角色 Bean:自动从懒加载中排除
  2. SmartInitializingSingleton 类型:这类 Bean 需要立即初始化
  3. 已经显式设置 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. 注意事项

  1. 启动性能提升:懒加载可以显著减少应用启动时间,因为大部分 Bean 直到真正使用时才创建
  2. 内存占用减少:Spring Boot 3.4 的懒加载特性可以让内存占用减少 80%
  3. 潜在问题:所有 Bean 都延迟初始化可能导致某些依赖关系问题,需要谨慎使用

总结

spring.main.lazy-initialization=true 配置的核心实现类是 LazyInitializationBeanFactoryPostProcessor 。这个 BeanFactoryPostProcessor 会在 Spring 容器刷新时遍历所有 BeanDefinition,并将那些没有被排除的 Bean 的 lazyInit 属性设置为 true,从而实现了全局的延迟初始化效果。

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm