SpringBoot:@Lazy懒加载注解

郎家岭伯爵 2024年01月31日 781次浏览

前言

在学习过程中遇到 @Lazy 注解,学习记录一下。

实现

理论部分

以下为在网络上找到的关于 @Lazy 注解的较为详细的解释:

Spring IoC(ApplicationContext)容器一般都会在启动的时候实例化所有单实例 Bean。如果我们想要 Spring 在启动的时候延迟加载 Bean,即在调用某个 Bean 的时候再去初始化,那么就可以使用 @Lazy 注解。

@Lazy 注解用来告诉 Spring 是否要延迟初始化指定的Bean。该注解可用于直接或间接用了 @Component 注解的任何类,或用了 @Bean 注释的方法。

如果 @Component 或 @Bean 定义上不存在 @Lazy 注解,则会进行初始化。如果存在 @Lazy 注解且设置 value 为 true,则 @Bean 或 @Component 定义的 Bean 将不会被初始化,直到被另一个 Bean 引用或从封闭的 BeanFactory 中显式检索。如果存在 @Lazy 且设置 value 为 false,则将在执行启动单例初始化的 Bean工厂启动时实例化 Bean。

如果 @Configuration 类上存在 @Lazy 注解,则表明该 @Configuration 中的所有 @Bean 方法都应延迟初始化。如果在 @Lazy 注解的 @Configuration 类中的 @Bean 方法上存在 @Lazy 注解且设置 value 为 false,则表明重写了“默认延迟”行为,并且应立即初始化 Bean。

除了 @Lazy 在组件初始化中的作用外,还可以将该注解放置在标有 @Autowired 或 @Inject 的注入点上:在这种情况下,它会为所有受影响的依赖项创建一个惰性解析代理,以替代使用 ObjectFactory 或 Provider。

说得直白一点就是:什么时候需要使用就什么时候去加载,而不是程序一启动就加载

实践部分

我们创建一个 SpringBoot 项目,通过设置 JVM 参数把堆内存设置为 512M

-Xmx512M -Xms512M

然后我们手动创建一个 1G 大小的对象:

package com.langjialing.helloworld.controlle1;

import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 郎家岭伯爵
 * @time 2024/1/31 15:29
 */
@RestController
@RequestMapping("/testLazy")
@Lazy
public class TestLazyController {
    private byte[] bytes = new byte[1024 * 1024 * 1024];
}

在加了 @Lazy 注解时,项目正常启动。

接下来我们注释掉 @Lazy 注解,项目启动报内存溢出异常

总结

学习记录下 @Lazy 注解。