【发布时间】:2018-08-23 01:09:23
【问题描述】:
我遇到了以下问题。我正在使用Weld 实现CDI。
我发现如果一个服务用@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() 的规范说:
提供一个完全构造和注入的 T 实例。
那么,有什么问题吗?是这样设计的还是这是一个错误?对我来说更重要的是:如何绕过这个问题?我需要我的服务是@ApplicationScoped。
【问题讨论】:
-
为什么调用
@PostConstruct方法对你很重要? -
@SteveC 有两个原因。 1.实用一。我的 init 方法中有一些逻辑,应该在服务初始化后立即执行。假设我为 init 使用了一些脆弱的资源,并希望确保它将在 init 阶段使用,而不是在我的应用程序工作的中间。 2)我很好奇这种不一致的原因
标签: java jakarta-ee cdi weld