前言
本文讨论如何在会话bean中实现异步业务方法,并从企业bean客户端调用它们。
叙述
异步方法调用
会话Bean可以实现异步方法,即在会话bean实例上调用方法之前,企业bean容器将控制返回给客户端的业务方法。然后,客户端可以使用Java SE并发API来检索结果,取消调用并检查异常。异步方法通常用于长时间运行的操作,处理器密集型任务,后台任务,增加应用程序吞吐量,或者如果方法调用结果不是立即需要的话,可以改进应用程序响应时间。
当会话bean客户端调用一个典型的非异步业务方法时,只有在方法完成之后,控制才会返回给客户端。但是,调用异步方法的客户端立即通过企业bean容器将控制返回给他们。这允许客户端在方法调用完成时执行其他任务。
创建异步业务方法
注释一个业务方法,javax.ejb.Asynchronous将该方法标记为异步方法,或者@Asynchronous在类级应用将会话Bean的所有业务方法标记为异步方法。公开Web服务的会话Bean方法不能是异步的。
异步方法必须返回接口的一个void或一个实现Future<V>。返回的异步方法void不能声明应用程序异常,但如果它们返回Future<V>,则可能会声明应用程序异常。例如:
@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException { ... }
这种方法将尝试处理订单的付款,并返回状态为String。即使支付处理器需要很长时间,客户端也可以继续工作,并在处理最终完成时显示结果。
该javax.ejb.AsyncResult<V>班是一个具体的实现的 Future<V>,作为返回异步结果的辅助类提供的接口。AsyncResult有一个结构作为参数的构造函数,可以很容易地创建Future<V>实现。例如,该processPayment方法将用于AsyncResult返回状态为String:
@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
...
String status = ...;
return new AsyncResult<String>(status);
}
结果将返回到企业bean容器,而不是直接返回给客户端,而企业bean容器则会将结果提供给客户端。会话bean可以通过调用javax.ejb.SessionContext.wasCancelled方法来检查客户端是否请求取消调用 。例如:
@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
...
if (SessionContext.wasCancelled()) {
// clean up
} else {
// process the payment
}
...
}
从企业Bean客户端调用异步方法
会话bean客户端像非异步业务方法一样调用异步方法。如果异步方法返回一个结果,Future<V>那么一旦方法被调用,客户端就会收到一个实例。此实例可用于检索最终结果,取消调用,检查调用是否完成,检查是否在处理期间抛出任何异常,并检查调用是否被取消。
从异步方法调用中检索最终结果
客户端可以使用其中一种Future<V>.get 方法来检索结果。如果处理调用的会话bean尚未完成处理,调用其中一个get方法将导致客户端暂停执行,直到调用完成。Future<V>.isDone在调用其中一个get方法之前,使用该 方法来确定处理是否已完成。
该get()方法返回结果作为Future<V>实例类型值中指定的类型。例如,调用 Future<String>.get()将返回一个String对象。如果方法调用被取消,调用get()导致 java.util.concurrent.CancellationException被抛出。如果调用在会话bean处理过程中导致异常,调用将get()导致 java.util.concurrent.ExecutionException抛出。ExecutionException可以通过调用该ExecutionException.getCause方法来检索 原因 。
该get(long timeout, java.util.concurrent.TimeUnit unit)方法与该方法类似get(),但允许客户端设置超时值。如果超时超时, java.util.concurrent.TimeoutException则抛出a。查看Javadoc TimeUnit的可用时间单位以指定超时值。
取消异步方法调用
调用实例cancel(boolean mayInterruptIfRunning)上的方法 Future<V>来尝试取消方法调用。该 cancel方法返回true如果取消是成功的, false如果方法调用不能被取消。
当调用无法取消时,该mayInterruptIfRunning 参数用于警告正在运行方法调用的会话bean实例,客户端试图取消调用。如果mayInterruptIfRunning设置为true,SessionContext.wasCancelled则会话bean实例的调用 将返回 true。如果mayInterruptIfRunning要设置false,SessionContext.wasCancelled会话bean实例的调用 将返回 false。
该Future<V>.isCancelled方法用于在调用完成异步方法调用之前检查方法调用是否被取消Future<V>.cancel。如果调用被取消,则isCancelled返回该方法true。
检查异步方法调用的状态
该Future<V>.isDone方法返回true如果会话bean实例完成处理的方法调用。该isDone方法返回true,如果异步方法调用正常完成时,被取消了,或者导致异常。也就是说,isDone只是表示会话bean是否已经完成处理调用。
小结
会话Bean的每个方法被同步调用(即客户端被堵塞,直到服务器端处理完成并返回结果)。会话Bean可以标记异步调用一个方法,然后客户端可以异步调用该方法。