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



我想要实现的是利用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;
}
}
}

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

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

感谢

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

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

因此,这可能是一个可行的策略,但需要注意:

  • 规范说"无状态会话bean实例通常是池化的"。您需要检查您选择的JavaEE服务器实现是否确实对它们进行了池化,因为(至少在一段时间内)其中一些服务器每次只会创建一个新实例;

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

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

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

对我来说,您需要实现一个Factory方法模式

为我阅读此信息EJB工厂级

最新更新