首页 > 解决方案 > 我可以将这个 EJB 的资源传递给另一个 EJB 吗?

问题描述

这更像是一个概念问题。

假设您有两个 EJB,A并且B.

首先A获取一些资源。它可以是任何东西:

  1. 注入@Resource
  2. 通过JNDI( new InitialContext()...) 获得的东西;
  3. javax.naming.Context(也许A'InitialContext指向 ' 以外的树BInitialContext
  4. EJB在数据库中找到(或创建)的实体;
  5. 引用第三个 EJB C
  6. 数据库连接;
  7. 数据库ResultSet(实时或缓存);
  8. 打开流(到文件,到套接字);
  9. Socket;
  10. File;
  11. [有创意]。

然后它调用B,将这些资源作为参数传递(直接或打包在其他对象中)。

这甚至合法吗?

让我们忽略Remote接口,因为其中许多资源无论如何都不能序列化。

但是对于本地接口呢?这是否违反规范?

为什么这很重要?

具体目标是创建一个通用@Stateless会话 bean 来执行@FunctionalInterface,如下所示:

@Stateless
public class FunctionalEJB {
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public <R> R executeInTransaction(Supplier<R> supplier) {
        return supplier.get();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void executeInTransaction(Runnable runnable) {
        runnable.run();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public <R> R executeInNewTransaction(Supplier<R> supplier) {
        return supplier.get();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void executeInNewTransaction(Runnable runnable) {
        runnable.run();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public <R> R executeOutsideTransaction(Supplier<R> supplier) {
        return supplier.get();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void executeOutsideTransaction(Runnable runnable) {
        runnable.run();
    }
}

那么这个 EJB 可以这样使用:

public class SomeClient extends SomeSuperClient {

    @Inject
    private FunctionalEJB ejb;

    // ...

    public method() {
        // ... many things before

        // open a special transaction to execute part of the logic
        ejb.executeInNewTransaction(() => {
            /***
              Everything done here is executed in a new transaction.
              This object (implicitly created by arrow function syntax)
               carries a lot of state as closure; this code here can access:
               - `SomeClient` fields
               - `SomeClient` methods (defined either in `SomeClient` itself, or `SomeSuperClient`, or some other subclass of `SomeClient`);
               - any variable defined in `method` before creating this transaction (as long as it is final, or effectively final).
             ****/
        });

        // ... many things after (the special transaction is already closed)
    }

    // ...

}

来自EJB 3.2 规范的引用

我从规范中收集了一些引用(查找“参数”)。其中一些为传递 - 至少 - 对其他会话 bean 的引用提供了理由。

尽管没有明确允许,但我列出的大多数情况(1-10,除了 4)在通过本地接口或无接口视图传递时似乎是合法的。

情况 4 稍微复杂一点,因为在一个事务中获得的实体 bean 可能在另一个事务中不可用(并且跨越会话 bean 边界可能会暂停当前事务 - 一个现有事务 - 并且可能创建另一个事务)。

【重点是我加的,不是出处】

3.2.3 在本地或远程客户端视图之间进行选择

3.4.3 Session Bean的业务接口

3.4.4 Session Bean的无接口视图

3.4.5 会话对象生命周期的客户端视图

3.6.5.2 对会话对象本地组件接口的引用

标签: ejb-3.0functional-interface

解决方案


推荐阅读