问题描述
我有以下课程:
@Repository
class A {
public void method1() {
...
}
}
@Component
class B implements C {
@Autowired
@Lazy
private A a;
public void method2() {
a.method1();
}
}
@Component
class D {
@Autowired
private List<C> c;
@PostConstruct
public void method3() {
// iterate on list c and call method2()
}
}
假设 Spring 初始化 bean 如下:
1. 创建第一个 bean B.在创建 bean B 时,由于 @Lazy
注释,字段 a
将不会被初始化.
2. 下一个 bean D 被创建.然后 method3()
将被执行,因为它被标记为 @PostConstruct
,但是 bean A 还没有被 Spring 触及.那么当 a.method1() 被调用时,Spring 会创建 bean A 并将其注入字段 a
还是会抛出 NullPointerException
?
Let's suppose Spring initializes the beans as following:
1. First bean B is created. When bean B is being created, field a
will not be initialized because of the @Lazy
annotation.
2. Next bean D is created. Then method3()
will get executed as it is marked with @PostConstruct
, but bean A is not yet touched by Spring. So when a.method1() will be called, then will Spring create bean A and inject it into the field a
or will it throw a NullPointerException
?
推荐答案
您需要了解,当您指定 @Lazy
作为注入的一部分时会发生什么.根据文档:
You need to understand, what's going on when you're specifying @Lazy
as part of injection. According to documentation:
除了用于组件初始化的作用外,@Lazy
注解也可以放在标有的注入点上@Autowired
或 @Inject
.在这种情况下,它导致注入一个延迟解析代理.
这意味着在启动时 Spring 将注入代理类的实例而不是 A
类的实例.代理类是自动生成的类,与A
类具有相同的接口.任何方法代理的第一次调用都会在 self 内部创建类 A
的实例.之后,所有方法调用都将重定向到代理内部的 A
类实例.
This means that on start Spring will inject instance of proxy class instead of instance of class A
. Proxy class is automatically generated class that have same interface as class A
. On first call of any method proxy will create instance of class A
inside of self. After that all calls of methods will be redirected to this instance of class A
inside of proxy.
所以没有理由害怕任何问题.
So there is no reason to be afraid of any problems.
这篇关于使用 Spring @Lazy 和 @PostConstruct 注解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!