gpt4 book ai didi

dependency-injection - 通过 CDI 注入(inject)时的多个有状态 EJB 实例

转载 作者:行者123 更新时间:2023-12-02 00:01:47 25 4
gpt4 key购买 nike

这主要是关于了解 差异 在注入(inject)有状态 EJB ( SFSB ) 与 @Inject 与注入(inject) @EJB 相比。

通过 @Inject 注入(inject)时,主要区别之一应该是 上下文感知 。所以我的假设是,如果我创建两个 @RequestScoped bean 并在每个 bean 中注入(inject)一个 SFSB 两次 (一次使用 @Inject ,一次使用 @EJB ),那么通过 SFSB109 bean 注入(inject)的 @Inject 将是相同的 @RequestScoped10409 bean _0409 _0409 个 _0409 bean _0409 _0409 个 _0409 _704通过 @EJB 注入(inject)的将是 个不同的实例

这个假设似乎是错误的,但我不明白为什么。 CDI 不应该知道两个 bean 都是 @RequestScoped 并因此注入(inject)相同的 SFSB 吗?为什么不是这样,或者我的测试代码有些缺陷?

这是我的 SFSB 及其界面:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Local;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;

import package.MyStateful;

@Stateful
@Local(MyStateful.class)
public class MyStatefulImpl implements MyStateful {

@PostConstruct
private void postConstruct() {
System.out.println("SFSB postconstruct ref: " + this.toString());
}

@PreDestroy
private void preDestroy() {
System.out.println("SFSB predestroy ref: " + this.toString());
}

@PrePassivate
private void prePassivate() {
System.out.println("SFSB prepassivate ref: " + this.toString());
}

@Override
public String myToString() {
return toString();
}
}

public interface MyStateful {
String myToString();
}

这是一个 @RequestScoped bean:
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import package.MyStateful;

@Named
@RequestScoped
public class MyFirstRequestScoped {

@Inject
MyStateful myStatefulByCDI;

@EJB
MyStateful myStatefulByEJB;

public MyStateful getMyStatefulByCDI() {
System.out.println("first#myStatefulByCDI proxy ref: " + myStatefulByCDI.toString());
System.out.println("first#myStatefulByCDI stateful ref: " + myStatefulByCDI.myToString());
return myStatefulByCDI;
}

public MyStateful getMyStatefulByEJB() {
System.out.println("first#myStatefulByEJB proxy ref: " + myStatefulByEJB.toString());
System.out.println("first#myStatefulByEJB stateful ref: " + myStatefulByEJB.myToString());
return myStatefulByEJB;
}

}

还有另一个名为 @RequestScopedMySecondRequestScoped bean 具有类似的实现。

当通过 JSFEL xhtml 页面调用它们时(没什么特别的,只是一个 <h:outputText value="#{myFirstRequestScoped.myStatefulByCDI}" /> 等来触发它们的创建),这是控制台输出(WebSphere ApplicationServer 8.5.5.0):
[1/4/14 12:39:11:759 CET] 000000dc SystemOut     O SFSB postconstruct ref: package.MyStatefulImpl@c03fcdee
[1/4/14 12:39:11:761 CET] 000000dc SystemOut O SFSB postconstruct ref: package.MyStatefulImpl@36b3bb10
[1/4/14 12:39:11:761 CET] 000000dc SystemOut O first#myStatefulByCDI proxy ref: package.EJSLocal0SFMyStatefulImpl_8d170245@48da7f98(BeanId(Project#ProjectEJB.jar#MyStatefulImpl, 5D0CBA11-0143-4000-E000-6A007F000001))
[1/4/14 12:39:11:762 CET] 000000dc SystemOut O first#myStatefulByCDI stateful ref: package.MyStatefulImpl@36b3bb10
[1/4/14 12:39:11:768 CET] 000000dc SystemOut O SFSB postconstruct ref: package.MyStatefulImpl@9b3971c7
[1/4/14 12:39:11:768 CET] 000000dc SystemOut O SFSB postconstruct ref: package.MyStatefulImpl@456cec27
[1/4/14 12:39:11:769 CET] 000000dc SystemOut O second#myStatefulByCDI proxy ref: package.EJSLocal0SFMyStatefulImpl_8d170245@48da7fa1(BeanId(Project#ProjectEJB.jar#MyStatefulImpl, 5D0CBA18-0143-4000-E001-6A007F000001))
[1/4/14 12:39:11:769 CET] 000000dc SystemOut O second#myStatefulByCDI stateful ref: package.MyStatefulImpl@456cec27
[1/4/14 12:39:11:769 CET] 000000dc SystemOut O first#myStatefulByEJB proxy ref: package.EJSLocal0SFMyStatefulImpl_8d170245@48da7f9b(BeanId(Project#ProjectEJB.jar#MyStatefulImpl, 5D0CBA0E-0143-4000-E000-6A007F000001))
[1/4/14 12:39:11:769 CET] 000000dc SystemOut O first#myStatefulByEJB stateful ref: package.MyStatefulImpl@c03fcdee
[1/4/14 12:39:11:769 CET] 000000dc SystemOut O second#myStatefulByEJB proxy ref: package.EJSLocal0SFMyStatefulImpl_8d170245@48da7fa1(BeanId(Project#ProjectEJB.jar#MyStatefulImpl, 5D0CBA18-0143-4000-E000-6A007F000001))
[1/4/14 12:39:11:770 CET] 000000dc SystemOut O second#myStatefulByEJB stateful ref: package.MyStatefulImpl@9b3971c7
[1/4/14 12:39:11:848 CET] 000000dc SystemOut O SFSB predestroy ref: package.MyStatefulImpl@36b3bb10
[1/4/14 12:39:11:849 CET] 000000dc SystemOut O SFSB predestroy ref: package.MyStatefulImpl@456cec27
[1/4/14 12:50:11:765 CET] 00000120 SystemOut O SFSB prepassivate ref: package.MyStatefulImpl@c03fcdee
[1/4/14 12:50:11:766 CET] 00000120 SystemOut O SFSB prepassivate ref: package.MyStatefulImpl@9b3971c7

所以看起来:
  • 创建了 4 个 SFSB 实例 ;我原以为这是 只是 3 。通过 @EJB 注入(inject)的那些不知道上下文,所以我认为如果为每个注入(inject)点创建它们就可以了。但是由于 CDI 应该知道上下文( @RequestScoped ),我认为 CDI 会重新注入(inject)已经创建的 SFSB
  • @Inject@EJB 之间的唯一区别似乎在于生命周期在通过 CDI 注入(inject)时自动管理 - 注释为 @PreDestroy 的方法是为那些 (35bbc7) 调用的。这些通过 @EJB(c03fcdee 和 9b3971c7)注入(inject)的文件稍后只会被钝化,并且似乎不会在任何时候被破坏。

  • 后者似乎是使用 @Inject 而不是 @EJB 的一个很好的理由,但我不明白的是 CDI 的上下文感知的真正含义,当有一个 SFSB 的新实例时,无论范围如何?

    顺便说一下,当使用 @SessionScoped bean 时,即使第二个 bean 是在链接到另一个页面后创建的(以确保通过 SFSB 注入(inject)的 @Inject 肯定已经存在),这也是一样的。此外,通过 SFSB 注入(inject)的 @EJB 实例 在 session 的生命周期内只创建一次 ,就像通过 @Inject 注入(inject)的那些一样 - 所以这些似乎也知道上下文,不知何故......?当混合 @SessionScoped@RequestScoped bean 时, @SessionScoped bean 获得 另一个注入(inject)的 SFSB 实例而不是 @RequestScoped bean,这很好 - 但不知何故,这似乎不是 CDI 的一个特性,因为这对于那些 _0x1919190406560565665656 个实例都是正确的通过 SFSB 注入(inject)的 @Inject 以及通过 @EJB 注入(inject)的 SFSB

    编辑: 观察到的行为的结论:
    通过 @Inject@EJB 注入(inject) SFSB 之间的唯一区别似乎是,在前一种情况下, CDI 在范围离开时会自动销毁,而在后一种情况下则不会。这样对吗?这会让我感到奇怪,因为我预计 CDI 的行为会有所不同......

    关于我遗漏的任何提示,即对“ojit_code”中的“C”的误解?我希望它不是某些 WebSphere“专长”...

    最佳答案

    为了将您的 SFSB 范围限定为请求,您需要为其提供 @RequestScoped范围。然后您应该看到注入(inject)的相同实例。现在因为这两个都是代理的,所以最简单的确认方法是从一个 bean 设置一些值,并从另一个 bean 获取值。

    关于dependency-injection - 通过 CDI 注入(inject)时的多个有状态 EJB 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20921606/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com