【问题标题】:javax.annotation.Injected outside of service is always null服务外的 javax.annotation.Injected 始终为空
【发布时间】:2025-12-02 02:45:01
【问题描述】:

我有一个 WildFly 服务器(没有 Spring),其中一个类需要进行注入。像这样的:

class Foo {
    @Inject
    private MyInterface myInterface;
    ...
}

但是每次创建类时myInterface 为空。 Foo 类不是在任何服务类中创建的,但调用是从服务类发生的。为了简化:

服务调用(具体为wsdl)→调用其他类的静态方法→该方法创建Foo的实例

实现MyService的类用@Named@ApplicationScoped注解。当@InjectMyInterface 在服务类中时(与Foo 中的代码完全相同),它会被正确注入。但不适用于非服务类。

【问题讨论】:

  • 类 Foo 是 CDI 还是 EJB?
  • 不是EJB,应该是CDI
  • Foo 是用什么注解的?
  • @JamesR.Perkins 它没有任何注释。是不是应该加注解?
  • 是的。要使 CDI 工作,所有 bean 都需要进行管理。 IoW 你不能做像new Foo() 这样的事情并让 CDI 工作。它需要管理所有相关组件的生命周期。

标签: java dependency-injection wildfly java-ee-8


【解决方案1】:

我相信您正在做以下事情: Foo foo = new Foo();

嗯,你不能。如果要在 Foo 内部注入,还需要让 CDI 管理 Foo。如果您使用new 自己创建它,那么它不是 CDI bean,因此它不能使用 CDI 功能。

所以首先你需要注释你的 Foo 类。注释取决于您希望它做什么。假设您需要为每个新的 http 请求创建一个实例,并且您需要它在 http 请求结束时终止。在这种情况下,它将是

@RequestScoped
class Foo {
    @Inject
    private MyInterface myInterface;
    ...
}

有关使用哪些注释的更多详细信息,请参见此处:https://docs.oracle.com/javaee/7/tutorial/cdi-basic008.htm

然后,在调用 Foo 的类上,您需要执行类似的操作

class FooCaller {
    @Inject
    private Foo foo;
    ...
}

请记住,FooCaller 调用者也需要是 CDI bean。

【讨论】: