gpt4 book ai didi

java - 初始化时不为@ApplicationScoped 调用@PostConstruct?

转载 作者:行者123 更新时间:2023-11-29 07:27:22 25 4
gpt4 key购买 nike

我遇到了以下问题。我正在使用 CDIWeld 实现。

我发现如果一个服务被注解为@ApplicationScoped然后@PostConstruct部分直到第一次使用该服务时才会被调用。这是重现此行为的代码:

import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.spi.CDI;

public class TestCdi {

public static void main(String[] args) {
try (WeldContainer weldContainer = new Weld().containerId("test").initialize()) {
FooService fooService = CDI.current().select(FooService.class).get();

fooService.test();
System.out.println("Done");
}
}

@ApplicationScoped
public static class FooService {

@PostConstruct
public void init() {
System.out.println("Post construct");
}

public void test() {
System.out.println("test");
}
}
}

因此,如果 fooService.test(); 被注释,则 FooService.init() 不会被调用。但是删除 @ApplicationScoped 它又可以工作了!

这对我来说似乎很奇怪,我找不到此类行为的描述。

此外,javax.inject.Provider.get() 的规范说:

Provides a fully-constructed and injected instance of T.

那么,问题是什么?它是这样设计的还是这是一个错误?对我来说更重要的是:如何绕过这个问题?我需要我的服务是 @ApplicationScoped

最佳答案

您看到的是 Weld 的 bean 初始化惰性方法。对于所有正常范围的 bean(除了来自 CDI 提供的范围的 @Dependent 以外的任何范围),您实际上注入(inject)了一个代理,该代理将调用委托(delegate)给上下文实例。在您尝试调用该代理上的任何 bean 方法之前,不会创建上下文实例。

CDI 规范没有强制 bean 是急切的还是惰性的,这是基于实现的选择(我不确定 Weld 文档现在是否提到了这一点)。在 Weld 的情况下,这主要是性能选择,因为其中许多 bean 将被初始化为空(例如,从未使用过)并且它会大大减慢引导速度。

请注意,这不是不一致的状态,对于 Weld 提供的每个范围,它都是这样工作的。它也不与 javax.inject.Provider.get() 矛盾,因为它没有说明必须在取回实例之前调用 @PostConstruct。此外,您实际上获得的实例是代理实例,并且该实例已完全初始化。

所以它归结为惰性和急切初始化的一般问题,哪个更好和/或哪个感觉更自然。

至于“解决方案”:

  • 您可以使用 EJB 的 @javax.ejb.Singleton 和使用 @Startup 注释。这将表现得非常像 @ApplicationScoped,所以它可能足够好如果你在 EE 环境中 当然。
  • 或者您可以在您的@ApplicationScoped bean 上创建一个虚拟的ping() 方法,并在您的应用程序启动时立即调用它。这将强制创建 bean,从而调用 @PostConstruct - 就像您在上面的代码示例中使用 test() 方法所做的那样。

作为旁注 - 在您的示例中,构造函数上的 @Inject 注释没有用。只有带有参数的构造函数才需要它。

关于java - 初始化时不为@ApplicationScoped 调用@PostConstruct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49278854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com