@Lazy注解解决循环依赖
@Lazy 是Spring框架中的一个注解,用于延迟一个bean的初始化,直到它第一次被使用。
在默认情况下,Spring容器会在启动时创建并初始化所有的单例bean。这意味着,即使某个bean直到很晚才被使用,或者可能根本不被使用,它也会在应用启动时被创建。@Lazy 注解就是用来改变这种行为的。
也就是说,当我们使用 @Lazy 注解时,Spring容器会在需要该bean的时候才创建它,而不是在启动时。这意味着如果两个bean互相依赖,可以通过延迟其中一个bean的初始化来打破依赖循环。
假设我们有两个类 ClassA 和 ClassB,它们之间存在循环依赖。我们可以使用 @Lazy 来解决这个问题:
@Component
public class ClassA {
private final ClassB classB;
@Autowired
public ClassA(@Lazy ClassB classB) {
this.classB = classB;
}
// ...
}
@Component
public class ClassB {
private final ClassA classA;
@Autowired
public ClassB(ClassA classA) {
this.classA = classA;
}
// ...
}
在这个例子中,ClassA 的构造器依赖 ClassB,但我们使用了 @Lazy 注解来标记这个依赖。这意味着 ClassB 的实例会在首次被实际使用时才创建,而不是在创建 ClassA 的实例时。这样,Spring容器可以先创建 ClassA 的实例(此时不需要立即创建 ClassB),然后创建 ClassB 的实例,最后解决 ClassA 对 ClassB 的依赖。
但是,还是忍不住提一句:过度使用 @Lazy 可能会导致应用程序的行为难以预测和跟踪,特别是在涉及多个依赖和复杂业务逻辑的情况下。
而且,循环依赖本身通常被认为是设计上的问题。所以应该尽量从根源处避免它。
@Lazy 可以用在bean的定义上或者注入时。以下是一些使用示例:
@Component
@Lazy
public class LazyBean {
// ...
}
在这种情况下,LazyBean 只有在首次被使用时才会被创建和初始化。
@Component
public class SomeClass {
private final LazyBean lazyBean;
@Autowired
public SomeClass(@Lazy LazyBean lazyBean) {
this.lazyBean = lazyBean;
}
}
在这里,即使SomeClass在容器启动时被创建,LazyBean也只会在SomeClass实际使用LazyBean时才被初始化。