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,从而实现了全局的延迟初始化效果。

相关推荐
小满zs1 小时前
Go语言第三章(五谷轮回)
后端·go
是小蟹呀^3 小时前
Spring Security + JWT 面试题整理
java·jwt·springsecurity
spencer_tseng5 小时前
Redis + Nacos.bat
java·windows·dos
霸道流氓气质5 小时前
SpringBoot中通用工具类库(Utils)封装与使用实践
spring boot·后端·python
troyzhxu6 小时前
列表查询的 GraphQL —— 一行代码终结你的 if-else 地狱!
java·springboot·graphql
孫治AllenSun6 小时前
【DataX】生产环境搭建DataX集群案例
java·开发语言·jvm
好好沉淀7 小时前
@NotBlank(message = “{xxx}“) 注解中花括号的含义
java
fīɡЙtīиɡ ℡7 小时前
内存泄漏产生的原因
java·spring·servlet
hkj88087 小时前
Ubuntu 切换java版本
java·linux·ubuntu