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.propertiesapplication.yml 中设置 spring.main.lazy-initialization=true 后,SpringApplication 实例的 lazyInitialization 属性会被设置为 true
注册阶段:
  • SpringApplication.run() 方法中,会调用 prepareContext() 方法
  • this.lazyInitializationtrue 时,Spring 会向容器注册一个 LazyInitializationBeanFactoryPostProcessor 的实例
执行阶段:
  • 在 Spring 容器的 refresh() 方法中,会调用所有 BeanFactoryPostProcessorpostProcessBeanFactory() 方法
  • LazyInitializationBeanFactoryPostProcessorpostProcessBeanFactory() 方法会遍历容器中的所有 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,从而实现了全局的延迟初始化效果。

相关推荐
无限大66 小时前
为什么"算法推荐"这么准?——从协同过滤到深度学习
后端
AIGCExplore6 小时前
Jenkins 全局配置及工具验证教程
java·servlet·jenkins
qq_318121596 小时前
Java大厂面试故事:Spring Boot、微服务与AI场景深度解析
java·spring boot·redis·微服务·ai·kafka·spring security
林太白6 小时前
Vite8 Beta来了,Rolldown携手Oxc
前端·javascript·后端
玛丽莲茼蒿7 小时前
javaSE 集合框架(五)——java 8新品Stream类
java·开发语言
程序员小假7 小时前
设计一个支持万人同时抢购商品的秒杀系统?
java·后端
L***d6707 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
37手游后端团队7 小时前
gorm回读机制溯源
后端·面试·github
古城小栈7 小时前
Rust 的 validator 库
开发语言·后端·rust
C雨后彩虹7 小时前
竖直四子棋
java·数据结构·算法·华为·面试