java - 使用 Spring @Lazy 和 @PostConstruct 注解

标签 java spring annotations lazy-evaluation postconstruct

我有以下类(class):

@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并将其注入(inject)到字段a中还是会抛出NullPointerException

最佳答案

您需要了解,当您指定 @Lazy 作为注入(inject)的一部分时会发生什么。根据documentation :

In addition to its role for component initialization, the @Lazy annotation may also be placed on injection points marked with @Autowired or @Inject. In this context, it leads to the injection of a lazy-resolution proxy.

这意味着 Spring 在启动时将注入(inject)代理类的实例而不是类 A 的实例。代理类是自动生成的类,与类A具有相同的接口(interface)。第一次调用任何方法时,代理都会在 self 内部创建类 A 的实例。之后,所有方法的调用都将被重定向到代理内部的类 A 的实例。

所以没有理由害怕任何问题。

关于java - 使用 Spring @Lazy 和 @PostConstruct 注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41443300/

相关文章:

Java:Runtime.exec() 只能通过控制台工作

java - 如何使用 GridBagLayout 使 JLabel 1 列宽,然后使 JTextField 2 列宽(总宽度 3 列)

java - Jackson数据绑定(bind)时如何获取Pojo名称引用的Json对象

gwt - Intellij IDEA 和 mvp4g APT 注解检查

java - @RequestMapping 在渲染方法中带有 2 个参数

python - 过滤我的注释

Java - 通过 TCP 连接发送无符号字节

java - 使用字节数组中的类而不进行反射?

java - Spring数据存储库查询包含的集合

Spring RMI 负载平衡/可扩展性