回答
Spring 利用三级缓存可以解决单例模式下的 Setter 注入或者字段注入方式的循环依赖,但是无法解决构造器注入的循环依赖。而使用 @Lazy
它可以破除循环依赖,但是我们也可以认为它没有解决,因为当 @Lazy
应用于一个 Bean 时,Spring 容器会为它生成一个代理对象,然后将这个代理对象注入。
所以,使用 @Lazy
确实是解决了循环依赖,但是在实际开发过程中不推荐使用 @Lazy
来解决循环依赖,出现了循环依赖问题属于类的设计问题,我们调整他们的结构来破除问题,而不是采用这种投机取巧的方式来规避问题。
详解
@Lazy 详解
在默认情况下,Spring 容器会在应用程序启动时初始化所有的单例 Bean。但是如果某个 Bean 使用了 @Lazy
,则 Spring 在启动阶段会暂时不对其进行实例化,而是在首次需要该 Bean 时再进行实例化。
使用 @Lazy
的目的可以加快应用的启动速度,尤其时特别适用于一些只在特定场景下才会使用的 Bean,节约了内存,同时也避免了没有意义的资源占用。
@Lazy
可以用在类上、方法上、用在注入点上、甚至可以和 @Configuration
。
- 用在类上
当 @Lazy
用在类上时,表示这个类的 Bean 只有在被首次使用时才会被实例化:
@Lazy
@Component
public class LazyBeanService {
public LazyBeanService () {
System.out.println("LazyBeanService 初始化");
}
public void doSomething() {
System.out.println("Doing something...");
}
}
- 用在方法上
当 @Lazy
应用到 @Bean
标注的方法上时,只对该方法定义的 Bean 进行懒加载,注意,不是整个类:
@Configuration
public class LazyBeanService {
@Bean
@Lazy
public LazyBeanService getLazyBeanService() {
return new LazyBeanService();
}
@Bean
public UnLazyBeanService getUnLazyBeanService() {
return new UnLazyBeanService();
}
}
这里就只有 LazyBeanService
会采用懒加载的方式,而 UnLazyBeanService
则不会。
- 用在注入点上