Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';在EJB中使用@Scoped有什么意义?_Java_Jakarta Ee_Ejb 3.0 - Fatal编程技术网

Java 什么';在EJB中使用@Scoped有什么意义?

Java 什么';在EJB中使用@Scoped有什么意义?,java,jakarta-ee,ejb-3.0,Java,Jakarta Ee,Ejb 3.0,通常我使用@RequestScoped或@SessionScoped(来自javax.enterprise.context)使用@inject注入对象(例如在faces bean中)。 我也在使用EJB。据我所知,一组无状态EJB拷贝(池)用于注入对象。存在多个副本的原因是为了确保EJB的一个实例不被并发访问。当谈到有状态EJB时(正如我所理解的那样),这种EJB的一个实例绑定到具体的注入点。它们是使用@EJB注入的(也包括无状态的) 我经常在网上看到将@Stateless或@Stateful与

通常我使用
@RequestScoped
@SessionScoped
(来自
javax.enterprise.context
)使用
@inject
注入对象(例如在faces bean中)。 我也在使用EJB。据我所知,一组无状态EJB拷贝(池)用于注入对象。存在多个副本的原因是为了确保EJB的一个实例不被并发访问。当谈到有状态EJB时(正如我所理解的那样),这种EJB的一个实例绑定到具体的注入点。它们是使用
@EJB
注入的(也包括无状态的)

我经常在网上看到将
@Stateless
@Stateful
@Scoped
结合使用的例子。它们是什么意思?

编辑:(试图澄清,因为此时无人回应):

我特别感兴趣的是,在创建EJB实例的那一刻,这样的范围注释是否会发生任何变化(如果它们发生变化的话)。 就我的理解而言:如果我有,
@EJB
注释字段,则将适当类的对象注入其中。如果这样的EJB是无状态的,容器只需从预先创建的实例池中获取自由实例。如有必要,可以调整池的大小。它是无状态的,因为不能保证对象在类的方法调用中被保留(即,类的字段包含对EJB的引用)

我们还可以使用有状态EJB,在这种情况下,在方法调用期间会保留一个实例。正如我所想,它将在每个对象创建时简单地注入一次。(还有一个在所有对象之间共享的单例EJB)

我在这里找不到EJB的@Scoped注释的用途

编辑2:

如果要通过EJB和DI(通过
@Inject
)机制注入类,则可以使用这种注释组合。然而,这只是一个特例,并不优雅。我是问你是否知道其他原因

编辑3:
请参阅我在arjan回答下的评论。

一个@Stateless或@Singleton bean可能被显式地限定范围,以防止其范围被自动修改为可能非法的范围。例如,这两种bean类型都不允许@RequestScope。有关更多信息,请参阅此链接:

@有状态(显式)限定范围很有意义。也就是说,如果没有作用域,作为程序员,您必须注意调用@Remove带注释的方法。这可能很难保证,因为这样一个bean通常不在单个方法中使用,您可以在finally块中调用@Remove方法。对于作用域,当作用域结束时,bean将被完全删除

此外,如果没有作用域,就不能始终使用注入来获取对有状态bean存根的引用。也就是说,每次注入发生时,您都会得到一个新实例。在请求作用域(JSF)支持bean中注入有状态bean时,这尤其麻烦,因为您打算在几个请求中保留有状态bean

然后,结合@Named,您还可以直接使用会话bean作为支持bean来扁平化应用程序层(参见示例)。显然,在这种情况下,您需要一个显式范围。现在,在较大的应用程序中,平坦化您的层可能不是一个最佳实践,但是对于较小的应用程序和/或刚开始使用JavaEE的人来说,肯定希望将业务逻辑直接放入支持bean中。然后要求支持bean能够访问“业务bean”通常拥有的相同类型的服务(主要是事务)

最后,Gavin King(CDI规范负责人)建议始终使用@Inject而不是@EJB。唯一的例外是远程EJB,其中仍然使用@EJB


关于EJB和CDI的混淆部分在于CDI是JavaEE中的一个新组件模型,而且仍然相对较新。尽管它们彼此集成得相当好,但它们仍然是两个不同的组件模型,并且还没有想到所有的最佳实践。Reza Rahman(例如,成员、EJB书籍作者和CDI实现CanDI的作者)建议,EJB模型可能在将来作为一组CDI服务进行改造。事实上,在JavaEE7中,一个步骤是将事务服务与EJB分离,并通过(CDI)注释使它们可用。

我不完全理解@CDI使用范围注释来决定注入哪个实例(之前使用的实例或新实例)。当我们使用@EJB时,我认为注入了某种代理对象。当我们调用该代理对象上的方法时,它会调用池中可用对象上的方法——如果该对象是无状态的。如果它是有状态的,那么这样的代理保证我们总是处理之前在这个注入点注入的同一个对象。这样的作用域可以理解为“注入点作用域”。@Scoped注释在这里如何应用?如果bean是有状态的,那么作用域注释确实用于选择指向要注入的实例的存根。如果没有作用域,每次都会有一个新的存根到有状态bean,这有点违背了有状态bean的目的。使用作用域的替代方法是从JNDI请求有状态bean,并将其分配给托管bean的实例变量,将其存储在HTTP会话中,等等。这是否意味着如果我在(例如)请求作用域的faces bean中插入了@EJB,并且这样的EJB也被注释为@SessionScope,同一实例将在一个会话中注入所有faces bean?(如果我使用@Inject来注入它,情况会是这样的)我只是检查了我的项目,它并没有像那样工作。我使用了@ApplicationScoped,所以ejb的一个实例应该放在bean的所有实例中。然而,如果使用@Inject,情况并非如此。所以,正如我所理解的,我应该有兼容的作用域和相同的注入点。对吗?@EJB是特定于EJB的注入