代码之家  ›  专栏  ›  技术社区  ›  Cyril Gandon niktrs

注入静态EJB,胡说?

  •  11
  • Cyril Gandon niktrs  · 技术社区  · 14 年前

    我想写这段代码:

    @Stateless
    public class MyEjb
    {
        @EJB
        private static MyOtherEjbWhichIWantStatic myOtherEjb;
    }
    

    不幸的是,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
    

    3 回复  |  直到 14 年前
        1
  •  27
  •   Community CDub    4 年前

    正如其他人指出的,规范不允许这样做,简短的版本是 @EJB 只有具有 main() 应用程序客户端容器

    在EJB中完全禁止读/写静态字段 (这是EJB限制的一部分)。从 Why can't I use nonfinal static fields in my enterprise bean?

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

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

    但是,虽然允许使用只读静态字段,但这不适合于ejb。无状态ejb可能是池化的,容器可能决定销毁它们(这是特定于实现的),并且您希望让容器选择要使用的实例,尤其是在分布式环境中。换言之,千万不要假设你和某个特定的实例有关。

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

        2
  •  1
  •   Michael Borgwardt    14 年前

    因为 the spec 不允许:

    5.2.3说明和注入

    如下所述 部分、领域或方法 容器管理的组件类 可能被注释为请求 来自应用程序组件的条目 将环境注入 类。[…] 适用于除 静态。

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

        3
  •  0
  •   Arjan Tijms Mike Van    12 年前

    根据JavaEE5规范,静态EJB的注入只允许在应用程序客户机主类中进行。