无状态 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
不适合。
- 这是
@Stateless
EJB 实例变量的正确用法吗?
-
@MessageDriven
更合适吗?
- 是否有更 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 池的方式。
我想要实现的是利用 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
不适合。
- 这是
@Stateless
EJB 实例变量的正确用法吗? -
@MessageDriven
更合适吗? - 是否有更 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 池的方式。