对作用域、ejb 和托管 bean 有一些疑问。
- 范围(javax.enterprise.context.ApplicationScope、javax.enterprise.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 使用范围
MyClass 是否应该实现 Serialized?我们是否可以说,因为托管 bean 被注入到 @Singleton 中,所以序列化永远不会发生?因此在部署时不会显示序列化错误?
- 如果是:如果我创建 MyClass @ApplicationScoped 和 @Stateful 并使用 @EJB 将其注入 SomeManager 中,那么在部署时我确实会收到有关序列化的错误。
- 如果否:为什么我没有得到瞬态记录器的一些 NullPointerExceptions(由于钝化/激活)?
CDI 范围是在 CDI 容器的上下文中评估的。也就是说,CDI 规范的设计者确保它可以与 EJB 和 jsf Managed Bean 一起使用。就是这样说的。
理想情况下,CDI 范围是使用上下文敏感的。 @ApplicationScoped 意味着 CDI bean 从创建实例到应用程序结束都有效。它由 CDI 容器管理,与 EJB bean 完全无关。但由于与 EJB 的互操作性,它可以被注入 (@Inject) 到 EJB @Singleton bean 中。 EJB 规范和 CDI 规范都没有要求 @Singleton bean 或 @ApplicationScope bean 可序列化。由于这是一个应用程序范围的实例,因此不需要钝化。
@SessionScope 使用当前容器希望的任何会话语义。例如,在 jsf 应用程序中,它的作用域通常为 HttpSession 的生命周期,但在没有 HttpSession 的 EJB 容器中,容器不会附加任何有意义的会话语义。它可能决定成为每个 @Stateless 事务或任何它希望的事务。由于会话可以序列化,因此规范通常要求 @SessionScoped beans 可序列化,但定义注入点的 bean(如果不是 @SessionScoped)则不需要可序列化。
@RequestScope 还遵循“原子”操作的单次执行的语义,例如http请求。在Web容器中,它通常与HttpRequest相关联,并且不要求它是可序列化的。在非 Web 上下文中,它可以与每次调用相关联,甚至可以与事务边界相关联(在注入 EJB 的情况下),或者当无法归属有意义的作用域时,它将在注入点默认为 @Dependent 作用域。
也就是说,任何 CDI bean 都可以注入到任何 EJB bean 中。通常,在不与 Web 容器关联的 EJB 容器中,@Dependent 和 @ApplicationScope 是唯一具有任何有意义用途的作用域。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)