Jakarta ee 可以将CDIBean注入JavaEE6中的静态变量吗?

Jakarta ee 可以将CDIBean注入JavaEE6中的静态变量吗?,jakarta-ee,cdi,Jakarta Ee,Cdi,这是否可能: @Inject @MessageTransport(MessageTransportType.SMS) public static MessageSender messageSender; 当我试图访问这个静态变量时,我得到了一个NPE。因此,我想知道,这在总体上是否是不可能的 提前感谢。通常不这样做,因为静态变量不能有作用域,也就是说,它只是整个类(读取应用程序)的一个作用域,因此没有意义,因为每个实例都会尝试根据当前作用域将其设置为新值。目前不可能,但理论上也不可能 另一个答

这是否可能:

@Inject
@MessageTransport(MessageTransportType.SMS)
public static MessageSender messageSender;
当我试图访问这个静态变量时,我得到了一个NPE。因此,我想知道,这在总体上是否是不可能的


提前感谢。

通常不这样做,因为静态变量不能有作用域,也就是说,它只是整个类(读取应用程序)的一个作用域,因此没有意义,因为每个实例都会尝试根据当前作用域将其设置为新值。

目前不可能,但理论上也不可能

另一个答案表明这是不可能的,但解释描述了注入在煤层2中的工作方式。我将试着从记忆中描述它。一些伪代码:

@Name("a")
class A() {
    @In
    B b;

    void something() {
        b.doTheThing();
    }
}
煤层2通过双射接收器支持注入。为了让拦截器工作,Seam创建了组件的代理实例。在这里,当调用
a.something
方法时,它将被截取,并且代理的
b
实例将确实被注入
a
的实例字段
b
。如果
B
所在的上下文在该时刻未处于活动状态,则注入将失败,
a.something
方法调用也将失败

现在让我们看一下CDI的类似示例:

class A() {
    @Inject
    B b;

    void something() {
        b.doTheThing();
    }
}
在CDI中仍然存在代理。但是注射的方式不同。CDI引入了上下文引用的概念。它是存储在
a.b
字段中的内容。当某件事被称为时,没有什么有趣的事情发生。在任何上下文中都不可能有
B
实例,而
a.something
方法仍然可以被调用。但是当调用
b.doTheThing
方法时,CDI开始寻找实际的
b
实例。例如,这时可能会得到
ContextNotActiveException

所以这似乎是可能的。我在旧的焊接现场发现,这可以解释为什么还没有实施:

静态注入

静态成员的注入有两个问题:

  • 一个类可以在多个应用程序之间共享,JavaEE规范没有为此定义规则
  • 在JavaEE之外,很难精确定义何时注入静态成员
尽管如此,这方面仍有几个重要的用例:

  • 记录器注入
  • 实体类的注入,以及
  • 注入到具有钝化范围的对象中
所以我们确实需要在这里支持一些东西。或许可以这样说:

  • 共享库中没有静态注入,并且
  • 静态字段是在bean的第一个实例被实例化之前被注入的(但是非bean类不支持静态注入)

有一个开放的CDI问题专门用于静态注入:。

显然您不应该这样做,但有时我认为您必须这样做,因为有时某些库中存在由其他对象实例化的对象(例如使用
ServiceLoader
),您希望注入它们。下面是一个你可以做到的技巧:

class StaticallyInjected {
  private static MyBean bean;

  void inject (@Observes @Initialized (ApplicationScoped.class) Object x,
               MyBean bean) {
    StaticallyInjected.bean = bean;
  }
}

这是一个非常好的答案。我只是想解释一下你为什么要这么做的另一个原因。如果您要迁移遗留应用程序,您可以使用静态注入来帮助减轻从静态到DI转换的痛苦。Stuart Douglas关于CDI注入方法的帖子:@VsevolodGolovanov不错的文章,但没有提到静态注入。我在评论中提到Stuart Douglas的文章,作为对“CDI注入的工作方式”。(.)这里的
Object x
在做什么?我从来没有考虑过它的实际类型。想法是借助于应用范围初始化,这就是注释所做的。我猜它是某种表示应用程序的对象,可能取决于CDI实现