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

时间:2017-01-31 09:05:12

标签: java java-ee ejb ejb-3.1 stateless-session-bean

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

我认为SLSB可能适用于保留本地无状态变量(不知道它是否是合适的定义) - 至少来自客户端/来电者POV。

@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 方式来实现它?
  4. 由于

2 个答案:

答案 0 :(得分:2)

与流行的看法相反,在SLSB中保持状态是完全可以的。它不能是客户端状态。 EJB 3.2规范的§4.7说:

  

术语“无状态”表示实例没有特定客户端的状态。但是,实例的实例变量可以包含跨客户端调用的方法调用的状态。此类状态的示例包括开放数据库连接和对企业bean对象的对象引用。

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

  • 规范说“无状态会话bean实例通常合并”。您需要检查所选择的JavaEE服务器实现是否确实实现了它们的集合,因为(至少有一段时间),其中一些只会每次都创建一个新实例;

  • 控制池中的bean数可能会很棘手。即使池已满,实现也可以继续创建bean实例,它永远不会将它们返回池中;

  • 如果从业务方法抛出任何类型的RuntimeException,那么将丢弃bean实例而不调用@PreDestroy回调(参见EJB 3.2 Spec的§9.3.1)。这将导致系统中的流程泄漏;

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

答案 1 :(得分:-1)

对我来说,您需要实施工厂方法模式;

请阅读此信息EJB Factory Class