Java 注入静态EJB,胡说八道?

Java 注入静态EJB,胡说八道?,java,static,dependency-injection,annotations,ejb-3.0,Java,Static,Dependency Injection,Annotations,Ejb 3.0,我想写这段代码: @Stateless public class MyEjb { @EJB private static MyOtherEjbWhichIWantStatic myOtherEjb; } 对于我来说,出于各种原因,我希望在类中注入一个EJB作为静态元素 不幸的是,Java对此并不满意 com.sun.enterprise.container.common.spi.util.InjectionException: Illegal use of static fie

我想写这段代码:

@Stateless
public class MyEjb
{
    @EJB
    private static MyOtherEjbWhichIWantStatic myOtherEjb;
}
对于我来说,出于各种原因,我希望在类中注入一个EJB作为静态元素

不幸的是,Java对此并不满意

com.sun.enterprise.container.common.spi.util.InjectionException: Illegal use of static field private static MyOtherEjbWhichIWantStatic myOtherEjb on class that only supports instance-based injection

我不明白,为什么我不能将一个静态EJB注入另一个EJB?

来自Java EE 5规范的静态EJB注入只允许在应用程序客户机主类中进行

对于除应用程序客户端主类以外的所有类,字段或方法不能是静态的。由于应用程序客户端使用与J2SE应用程序相同的生命周期,因此应用程序客户端容器不会创建应用程序客户端主类的任何实例。而是调用静态main方法。为了支持应用程序客户机主类的注入,为注入而注释的字段或方法必须是静态的

我不明白,为什么我不能注射疫苗 将静态EJB转换为另一个EJB

因为不允许:

5.2.3说明和注射

如下文所述 部分,特定领域或方法 容器管理的组件类 可注释为请求 从应用程序组件的 将环境注入到 班级。[…]适用于除 应用程序客户端主类 字段或方法不能为空 静态。


请注意,异常(应用程序客户端主类)只存在,因为这些类从未实例化。基本上,静态字段通常是有问题的,在应用服务器中更是如此,因为它们可以避免请求处理线程和事务的分离,这是使用应用服务器的首要目的。

正如其他人指出的,这是规范不允许的,简短的版本是,
@EJB
注释仅支持带有
main()
函数的类中的静态成员(请参阅ejb3.0规范和app-client容器)

为什么会这样?首先,读/写静态字段在EJB中是完全禁止的(这是EJB限制的一部分)。从

EJB中不允许使用非最终静态类字段,因为此类字段使企业bean难以或无法分发。静态类字段在特定类的所有实例之间共享,但仅在单个Java虚拟机(JVM)中共享。更新静态类字段意味着在类的所有实例之间共享字段值的意图。但是,如果一个类同时在多个JVM中运行,则只有那些与更新实例在同一JVM中运行的实例才能访问新值。换句话说,如果在单个JVM中运行,非最终静态类字段的行为将不同于在多个JVM中运行。EJB容器保留跨多个JVM(运行在同一台服务器上或任何一个服务器集群上)分发企业bean的选项。不允许使用非最终静态类字段,因为企业bean实例的行为将根据它们是否分布而有所不同

如果静态类字段标记为
final
,则可以使用这些字段。由于最终字段无法更新,因此容器可以分发企业bean的实例,而不必担心这些字段的值变得不同步

但是,虽然允许使用只读静态字段,但这不适合EJB。无状态EJB可能被池化,容器可能决定销毁它们(这是特定于实现的),并且您希望让容器选择要使用的实例,特别是在分布式环境中。换句话说,永远不要假设您被绑定到某个特定实例

所以最后,是的,这是胡说八道