JAVA EE CDI Scopes、EJB和托管bean序列化



对作用域、ejb和托管bean有一些问题。

  1. 作用域(javax.enterprise.context.ApplicationScope、javax.enterface.context.SessionScope)是否仅适用于EJB?或者它们是针对所有托管的bean?直到今天,我还很确定这是为所有管理的豆子准备的
  2. 在我的应用程序中,我们有:

    @ApplicationScoped
    public class MyClass implements MyNonSerializableInterface {
      @Inject  
      private transient NonSerializableLogger transientLogger;
      @Inject
      private NonSerializableLogger logger;
     ...
    }
    

    和一些经理:

    @Singleton
    public class SomeManager {
        @Inject private MyClass myClass;  
    }
    

    和一个网络服务:

    @Path("some")
    public class SomeWebService {
        @Inject private SomeManager;
    }
    

容器(部署时间)或编译器对此没有抱怨,这正常吗?

我想:

"使用会话、应用程序或会话范围的bean必须是可序列化的,但使用请求范围的bean不必是可序列化。"JAVA EE Using Scopes

MyClass是否应该实现Serializable?我们可以说,因为托管bean被注入到@Singleton中,所以序列化永远不会发生吗?因此,在部署时没有显示序列化错误?

  1. 如果是:如果我使MyClass@ApplicationScoped和@Stateful并使用@EJB将其注入SomeManager,那么在部署时我确实会收到一个关于序列化的错误
  2. 如果否:为什么我不为瞬态记录器获取一些NullPointerException(由于分段/激活)

CDI作用域是在CDI容器的上下文中评估的。也就是说,CDI规范的设计者确保了它可以与EJB和jsf-ManagedBean一起操作。话虽如此。

  1. CDI作用域在理想情况下是使用敏感的上下文@ApplicationScoped意味着CDI bean从创建实例到应用程序结束都将存在。它由CDI容器管理,与EJB bean完全无关。但是由于与EJB的互操作性,它可以被注入(@Inject)到EJB@Singleton bean中。EJB规范和CDI规范中都没有要求@Singletonbean或@ApplicationScopebean是可序列化的。由于这是一个应用范围广泛的实例,因此不需要钝化。

  2. @SessionScope使用当前容器所希望的会话的任何语义。例如,在jsf应用程序中,它的范围通常为HttpSession的生存期,但在没有HttpSession的EJB容器中,容器不会附加任何有意义的会话语义。它可能会决定是一个每个@Stateless的交易或任何它希望的事情。由于会话可以序列化,所以规范通常要求@SessionScoped bean是可序列化的,但定义注入点的bean(如果不是@sessionScoded)则不需要是可串行的。

  3. @RequestScope还遵循"原子"操作的单次执行的语义,例如httprequest。在web容器中,它通常与HttpRequest相关联,并且不要求它是可序列化的。在非web上下文中,它可以与每次调用相关联,甚至与事务边界相关联(在注入EJB的情况下),或者在注入点默认为@Dependent作用域,此时无法对任何有意义的作用域进行属性。

也就是说,任何CDIBean都可以注入到任何EJB bean中。通常,在与web容器不关联的EJB容器中,@Dependent和@ApplicationScope是唯一具有任何有意义用途的作用域。

最新更新