无状态 EJB 本地(实例)变量

Stateless EJB local (instance) variable

我想要实现的是利用 EJB 功能并使用某种自动池。

我认为 SLSB 可能是合适的,当保留一个 本地无状态变量 (不知道它是否是一个合适的定义)时 - 至少从 client/caller 视角

@Stateless
public class CommunicationService implements Serializable
{
    private Process process;

    @PostConstruct
    //@PostActivate maybe?
    public void startProcess()
    {
        try
        {
            process = new ProcessBuilder("running a temporary daemon").start();
        }
        catch(IOException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        } 
    }


    @PreDestroy
    //@PrePassivate maybe?
    public void endProcess()
    {
        if(process.isAlive())
        {
            process.destroy();

            boolean terminated = false;
            try
            {
                terminated = process.waitFor(5, TimeUnit.SECONDS);
            }
            catch(InterruptedException e)
            {
                // ignore
            }

            if(!terminated)
            {
                process.destroyForcibly();
            }
        }
    }

    public int send(String message)
    {
        // do something with the process - may take a long time
        // this is just an example

        PrintStream printStream = new PrintStream(process.getOutputStream());
        printStream.println(message);

        try
        {
            return process.getInputStream().read();
        }
        catch(IOException e)
        {
            return -1;
        }
    }
}

请注意,我想要一个进程池,所以 @Singleton 不适合。

  1. 这是 @Stateless EJB 实例变量的正确用法吗?
  2. @MessageDriven 更合适吗?
  3. 是否有更 EE 的方法来实现它?

谢谢

对我来说,你需要实现一个工厂方法模式 ;

为我阅读此信息EJB Factory Class

与流行的看法相反,在 SLSB 中维护状态是完全可以的。它不能是 client 状态。 EJB 3.2 规范的第 4.7 节说:

The term “stateless” signifies that an instance has no state for a specific client. However, the instance variables of the instance can contain the state across client-invoked method calls. Examples of such state include an open database connection and an object reference to an enterprise bean object.

因此,这可能是一个可行的策略,但有一些注意事项:

  • 规范说 "stateless session bean instances are typically pooled"。您需要检查您选择的 JavaEE 服务器实现是否确实将它们汇集在一起​​,因为(至少有一段时间)它们中的一些每次都会创建一个新实例;

  • 控制池中 bean 的数量可能很棘手。即使池已满,实现也可能会继续创建 bean 实例,只是永远不会 returns 它们进入池;

  • 如果业务方法抛出任何类型的 RuntimeException,则将丢弃 bean 实例而不调用 @PreDestroy 回调(参见 EJB 3.2 规范的§9.3.1)。这将导致您的系统出现进程泄漏;

因此,您需要熟悉服务器管理 SLSB 池的方式。