拼多多一面:Spring @Lazy 可以解决循环依赖吗?

开发 前端
本文我们分析了 @Lazy注解的工作原理,主要用途以及如何使用它。@Lazy是 Spring提供的一个强大工具,用于控制 Bean的初始化时机,帮助开发者优化应用的性能和资源使用。

在实际工作中,@Lazy注解的主要用途是什么?它是如何工作的?@Lazy可以解决循环依赖吗?我们该如何使用它?这篇文章,我们来聊一聊。

1. 主要作用

首先,让我们看看@Lazy注解的源码,截图如下:

通过源码,我们可以看到:@Lazy注解是一个标记注解,用于标记 bean会被延迟初始化。@Lazy注解可以用于类,方法,构造器,参数,字段上。

从整体上看,@Lazy注解的作用主要有下面三点:

(1) 延迟初始化Bean

  • 默认情况下,Spring容器在启动时会立即创建和初始化所有单例(singleton)Bean,这称为预加载(eager initialization)。
  • 使用@Lazy注解可以将Bean的初始化延迟到第一次使用时才进行,即懒加载(lazy initialization)。

(2) 优化资源使用和启动时间

  • 对于一些在应用启动时不一定会使用的Bean,延迟初始化可以减少启动时间,提高应用的响应速度。
  • 减少不必要的资源消耗,尤其是在资源密集型的应用中尤为重要。

(3) 解决循环依赖问题

在某些情况下,Bean之间存在循环依赖,提前初始化可能导致问题。使用@Lazy可以打破这种循环依赖。

2. 工作原理

在分析完@Lazy注解的主要作用后,接下来我们来看看@Lazy注解的工作原理,这里归纳为下面三点:

(1) 代理机制

  • Spring通过创建代理对象来实现Bean的延迟初始化。当一个懒加载Bean被引用时,Spring并不会立即创建其实例,而是创建一个代理对象。
  • 当对代理对象的方法进行实际调用时,代理会触发Bean的真实创建和初始化。

(2) 延迟加载的实现步骤

  • 容器启动时:Spring扫描到带有@Lazy注解的Bean,不会立即实例化,而是生成一个代理对象并注册到容器中。
  • 第一次访问时:当应用代码首次引用该Bean时,代理对象会触发实际Bean的创建和依赖注入过程。

(3) 与@Scope搭配使用

@Lazy通常与@Scope("singleton")或@Scope("prototype")搭配使用,以控制单例或原型Bean的懒加载行为。

3. 使用方法

根据上面我们分析@Lazy注解源码时,我们知道@Lazy注解可以用于类,方法,构造器,参数,字段上,因此,我们将分别举例来说明它们是如何使用的。

(1) 在Bean定义上使用@Lazy

@Component
@Lazy
public class LazyBean {
   // Bean内容
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

(2) 在配置类中使用@Lazy注解

@Configuration
public class AppConfig {

   @Bean
   @Lazy
   public LazyBean lazyBean() {
       return new LazyBean();
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

(3) 在依赖注入点使用@Lazy

对特定的依赖进行懒加载,而不是整个Bean。

@Component
public class AnotherBean {

   private final LazyBean lazyBean;

   public AnotherBean(@Lazy LazyBean lazyBean) {
       this.lazyBean = lazyBean;
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

4. 注意事项

在日常工作中,我们使用@Lazy 注解,需要注意以下事项:

  • 代理开销:使用@Lazy会引入代理对象,可能会带来一定的性能开销,尤其是在高频调用的场景下需要权衡利弊。
  • 配置复杂性:过度使用懒加载可能导致配置复杂,难以跟踪Bean的初始化时机,影响调试和维护。
  • 测试与调试:在测试和调试时,延迟初始化可能会导致某些Bean未按预期初始化,需要注意测试环境的配置。

5. 总结

本文,我们分析了 @Lazy注解的工作原理,主要用途以及如何使用它。@Lazy是 Spring提供的一个强大工具,用于控制 Bean的初始化时机,帮助开发者优化应用的性能和资源使用。

回到文章的标题:@Lazy注解能解决循环依赖吗?

答案:可以解决基于构造器注入产生的循环依赖。详情可以参考我往期的文章:Spring循环依赖,一个注解搞定!

责任编辑:赵宁宁 来源: 猿java
相关推荐

2024-10-15 10:59:18

Spring MVCJava开发

2024-10-17 16:58:43

2025-03-13 10:01:47

2025-03-12 09:36:23

AspectJAOP开发

2022-08-13 12:07:14

URLHTTP加密

2022-05-11 22:15:51

云计算云平台

2021-04-29 07:18:21

Spring IOC容器单例

2024-05-15 16:41:57

进程IO文件

2019-11-26 14:30:20

Spring循环依赖Java

2020-02-10 15:50:18

Spring循环依赖Java

2023-10-07 08:40:57

缓存属性Spring

2025-03-18 08:30:00

Spring开发java

2025-03-28 08:10:00

Spring自动装配Java

2022-07-26 00:00:02

TCPUDPMAC

2025-03-20 09:59:55

Spring@ProfileJava

2022-08-18 17:44:25

HTTPS协议漏洞

2024-06-05 11:43:10

2023-11-29 20:03:03

2023-07-13 09:16:47

循环队列指针front​

2020-12-29 08:34:08

spring循环依赖开发
点赞
收藏

51CTO技术栈公众号