对作用域、ejb和托管bean有一些问题。
- 作用域(javax.enterprise.context.ApplicationScope、javax.enterface.context.SessionScope)是否仅适用于EJB?或者它们是针对所有托管的bean?直到今天,我还很确定这是为所有管理的豆子准备的
-
在我的应用程序中,我们有:
@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中,所以序列化永远不会发生吗?因此,在部署时没有显示序列化错误?
- 如果是:如果我使MyClass@ApplicationScoped和@Stateful并使用@EJB将其注入SomeManager,那么在部署时我确实会收到一个关于序列化的错误
- 如果否:为什么我不为瞬态记录器获取一些NullPointerException(由于分段/激活)
CDI作用域是在CDI容器的上下文中评估的。也就是说,CDI规范的设计者确保了它可以与EJB和jsf-ManagedBean一起操作。话虽如此。
-
CDI作用域在理想情况下是使用敏感的上下文@ApplicationScoped意味着CDI bean从创建实例到应用程序结束都将存在。它由CDI容器管理,与EJB bean完全无关。但是由于与EJB的互操作性,它可以被注入(@Inject)到EJB@Singleton bean中。EJB规范和CDI规范中都没有要求@Singletonbean或@ApplicationScopebean是可序列化的。由于这是一个应用范围广泛的实例,因此不需要钝化。
-
@SessionScope使用当前容器所希望的会话的任何语义。例如,在jsf应用程序中,它的范围通常为HttpSession的生存期,但在没有HttpSession的EJB容器中,容器不会附加任何有意义的会话语义。它可能会决定是一个每个@Stateless的交易或任何它希望的事情。由于会话可以序列化,所以规范通常要求@SessionScoped bean是可序列化的,但定义注入点的bean(如果不是@sessionScoded)则不需要是可串行的。
-
@RequestScope还遵循"原子"操作的单次执行的语义,例如httprequest。在web容器中,它通常与HttpRequest相关联,并且不要求它是可序列化的。在非web上下文中,它可以与每次调用相关联,甚至与事务边界相关联(在注入EJB的情况下),或者在注入点默认为@Dependent作用域,此时无法对任何有意义的作用域进行属性。
也就是说,任何CDIBean都可以注入到任何EJB bean中。通常,在与web容器不关联的EJB容器中,@Dependent和@ApplicationScope是唯一具有任何有意义用途的作用域。