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实现