开发将调用 EJB 异步方法的客户机代码
您可以使用本主题中的样本代码来开发用于调用 EJB 异步方法的客户机代码。
开始之前
public interface AcmeRemoteInterface {
void fireAndForgetMethod ();
Future<Integer> methodWithResults() throws AcmeException1, AcmeException2;
}
@Stateless
@Remote(AcmeRemoteInterface.class)
@Asynchronous
public class AcmeAsyncBean {
public void fireAndForgetMethod () {
// do non-critical work
}
public Integer methodWithResults() {
Integer result;
// do work, and then return results
return result;
}
}
关于此任务
过程
- 创建用于调用异步方法的客户机代码,该异步方法将不返回任何结果且有时称为即发即弃方法。
这种类型的异步方法无法引起应用程序异常。
但是,可能会发生一些必须解决的系统异常。
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // Asynchronous method never dispatched, handle system error }
- 创建用于调用异步方法的客户机代码,在该异步方法中可返回结果。
- 创建用于调用异步方法的客户机代码,在该异步方法中,客户机最多等待 5 秒(在此时间段内,将阻塞客户机线程)即可接收结果。异常处理需求与上一步相同。例如:
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- 创建用于调用异步方法的客户机代码,在异步方法中不立即获取结果。执行该方法之后,客户机将检索结果。此方案可防止阻塞客户机线程,并且客户机在轮询结果时可空闲出来执行其他工作。异常处理需求与上述步骤相同。在本示例中,客户机定期轮询 Future<V> 对象以确定异步方法何时完成执行。例如:
while (!myFutureResult.isDone()) { // Execute other work while waiting for the asynchronous method to complete. } // This call is guaranteed not to block because isDone returned true. myResult = myFutureResult.get();
- 创建用于调用异步方法的客户机代码,在该异步方法中,客户机最多等待 5 秒(在此时间段内,将阻塞客户机线程)即可接收结果。异常处理需求与上一步相同。例如:
- 创建客户机代码以处理应用程序异常。 该客户机代码会调用异步方法,该异步方法将在 Future<V> 对象中返回应用程序异常。以下示例说明了在确定已发生的应用程序异常时所需的异常处理代码。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method never dispatched, handle exception } // Method is eventually dispatched. Wait for results. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Determine which application exception that occurred during the // asynchronous method call. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // Handle AcmeException1 } else if (theCause instanceof AcmeException2) { // Handle AcmeException2 } else { // Handle other causes. } } catch ( ... ) { // Handle other exception. }
- 创建客户机代码以识别由异步方法调用在执行期间抛出的系统异常。
以下示例说明了在确定是否发生系统异常时所需的异常处理代码。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method was not dispatched; handle exception. } // Method will eventually be dispatched so block now and wait for results try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Find the exception class that occurred during the asynchronous method Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // Handle the EJBException that might be wrapping a system exception // which occurred during the asynchronous method execution. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Handle the system exception } } else ... // handle other causes } catch (...) { // handle other exceptions }
- (可选)创建客户机代码以取消异步方法调用。如果此尝试成功,那么 Future.isCancelled 方法将返回 true 并且 Future.get 方法将引起 CancellationException。 以下示例说明了取消异步方法调用所需的代码。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // Asynchronous method was not dispatched. } else { // Asynchronous method already started executing. The bean can still check // whether an attempt was made to cancel the call. } if (myFutureResult.isCancelled()) { // Asynchronous method call did not start executing because the cancel // method returned true in a previous line of the example. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Handle the exception that occurs because the cancel method returned true // in a previous line of the example. }
- (可选)创建 Bean 代码以检查客户机是否已尝试取消异步方法调用。
以下示例说明了检查客户机是否已尝试取消异步方法调用时所需的 Bean 代码。如果客户机已尝试取消工作,那么 SessionContext.wasCancelCalled 方法将返回 true,并且 Bean 代码可以避免不必要的工作。
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Do one piece of long-running work. // Before continuing, check whether the client attempted to cancel this work. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- 从异步方法调用传递回多个输出值。
在某些情况下,方法必须传递回多个数据片段。
完成此项任务的一种方法是使用按引用传递语义。在此方法中,对象将作为参数传递到方法中,再由该方法更新,然后,所更新的值可供客户机使用。此方法对异步方法也有效,但不是最佳模式。
要返回多个数据片段,请在方法所返回的 Future 对象内创建一个包装程序。在此方法中,定义了包含实例变量的包装程序对象,这些实例变量用于存放必须返回的不同数据片段。异步方法会将这些数据片段放到包装程序对象内并返回该对象,然后,客户机代码从 Future 对象检索此数据。
在包装程序对象内嵌入多个数据片段是本地或远程的透明模式,该模式可识别结果具体可用的时间。相对而言,传统的按引用传递方法向客户机提供的方式并不容易确定结果何时可用。直到运行异步方法时才更新传入的对象,客户机除了通过使用 Future.isDone() 或 Future.get() 方法来询问 Future 对象外,也不能确定何时更新传入的对象。
// This is the result object that is returned from the asynchronous method. // This object is wrappered in a Future object, and it contains the two pieces of data // that must be returned from the method. class ResultObject { public Boolean myResult; pubilc String myInfo; }
// This is the asynchronous method code that gets the results and returns them. @Asynchronous public Future<ResultObject> asyncMethod1(Object someInputData) { boolean result = doSomeStuff(); String info = doSomeMoreStuff(); ResultObject theResult = new ResultObject(); theResult.myResult = result; theResult.myInfo = info; return new javax.ejb.AsyncResult<ResultObject>(theResult); }
// This is the client code that obtains the ResultObject, and then extracts the needed data from it. Future<ResultObject> myFutureResult = myBeanRef.asyncMethod1(someInputData); ResultObject theResult = myFutureResult.get(); boolean didItWork = theResult.myResult; String explanation = theResult.myInfo;
子主题
EJB 异步方法的客户机编程模型
如 Enterprise JavaBeans (EJB) 3.1 规范中所述,您可以通过以下接口类型来调用 EJB 异步方法:本地业务、远程业务或无接口视图。不允许通过 EJB 2.1 客户机视图或 Web Service 视图进行调用。EJB 异步方法的客户机编程模型
如 Enterprise JavaBeans (EJB) 3.1 规范中所述,您可以通过以下接口类型来调用 EJB 异步方法:本地业务、远程业务或无接口视图。不允许通过 EJB 2.1 客户机视图或 Web Service 视图进行调用。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_clientcode
文件名:tejb_clientcode.html