我想要实现的是利用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
s不合适。
- 这是
@Stateless
EJB实例变量的正确使用吗 @MessageDriven
更合适吗- 是否有更多EE的方法来实现它
感谢
与流行的观点相反,在SLSB中保持状态是完全可以的。它不能是客户端状态。EJB 3.2规范的§4.7规定:
术语"无状态"表示实例没有特定客户端的状态。但是,实例的实例变量可以包含客户端调用的方法调用之间的状态。这种状态的示例包括开放数据库连接和对企业bean对象的对象引用。
因此,这可能是一个可行的策略,但需要注意:
-
规范说"无状态会话bean实例通常是池化的"。您需要检查您选择的JavaEE服务器实现是否确实对它们进行了池化,因为(至少在一段时间内)其中一些服务器每次只会创建一个新实例;
-
控制池中bean的数量可能很棘手。即使池已满,实现也可能继续创建bean实例,只是永远不会将它们返回到池中;
-
如果从业务方法抛出任何类型的RuntimeException,那么bean实例将被丢弃,而不调用@PreDestroy回调(请参见EJB 3.2规范的§9.3.1)。这将导致系统中的进程泄漏;
因此,您需要熟悉服务器管理SLSB池的方式。
对我来说,您需要实现一个Factory方法模式;
为我阅读此信息EJB工厂级