我有几个异步作业,我想透明地处理异常。我想将异常处理逻辑放在另一个组件/类中。使用 Seam 2,我扩展了一个异常处理程序类。
例如,我想引发一个包含异常的事件,以便我可以让多个组件在它们认为合适的时候对其进行操作。最常见的一种是通知管理员。
谢谢,
沃尔特
我有几个异步作业,我想透明地处理异常。我想将异常处理逻辑放在另一个组件/类中。使用 Seam 2,我扩展了一个异常处理程序类。
例如,我想引发一个包含异常的事件,以便我可以让多个组件在它们认为合适的时候对其进行操作。最常见的一种是通知管理员。
谢谢,
沃尔特
以下是第三部分中的一个示例:EJB 3.1中的新特性,您可能可以对其进行调整:
会话 Bean 的异步调用
对于许多企业应用程序来说,异步处理是一个令人惊讶的普遍要求。一些最明显的用例是触发即发即弃的后台进程,处理长时间运行的任务,同时保持用户界面易于接受,或者通过利用并行处理的优势来简单地增加应用程序吞吐量。目前在 Java EE 应用程序中实现异步处理的最简单方法是使用消息驱动 Bean。事实上,EJB 3 in Action 中的第一个 Message Driven Bean 示例就是用来实现异步订单计费的。更准确地说,消息驱动 Bean (
OrderBillingMDB
) 在订单确认后异步向客户开具账单,并在完成后使用账单尝试的结果更新订单信息。图 1 显示了这种情况:
图 1:异步订单计费
虽然使用消息驱动 Bean 进行异步处理当然可行,但它也迫使您处理消息传递和 JMS,即使对于相对轻量级的功能也是如此。这正是异步会话 bean 调用旨在解决的问题。使用此增强功能,您可以简单地通过使用注解对会话 bean 方法进行注解来进行异步处理
@Asynchronous
。让我们看一下使用该功能进行异步计费的重构 EJB 3 in Action 示例:@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public void billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); order.setStatus(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); order.setStatus(OrderStatus.BILLING_FAILED); } finally { update(order); } } ... }
由于
@Asynchronous
注解,当客户端调用OrderBillingService.billOrder
方法时,调用将立即返回,而不是阻塞,直到billOrder
方法执行完毕。EJB 容器将确保方法被异步执行(可能在后台使用消息传递)。可以看到,异步方法的返回类型是 void。绝大多数异步 Session bean 方法可能就是这种情况。但是,EJB 3.1 也可以支持返回类型java.util.concurrent.Future<V>
,其中V
表示异步调用的结果值。如果你不熟悉它,Future<V>
接口允许您执行诸如取消异步调用、检查调用是否完成、检查异常以及获取异步调用的结果等操作。Future<V>
在此处查看接口 的文档:http: //java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html。让我们快速看一下使用 Future 返回类型的示例。在billOrder
前面示例的方法中,我们根据计费尝试的结果设置订单的状态并更新订单。让我们假设调用者自己更新订单并想知道计费尝试的状态是什么。我们可以通过billOrder
如下重构方法来做到这一点:@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public Future<OrderStatus> billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); return new AsyncResult<OrderStatus> (OrderStatus.BILLING_FAILED); } } ... }
该
javax.ejb.AsyncResult<V>
对象是Future<V>
接口的便利实现。它将异步调用的结果作为构造函数参数。然而,没有什么能阻止你使用你自己的实现Future<V>
。异步调用支持其他一些简洁的功能,如交付保证和事务发送语义。有关详细信息,请查看规范草案。
如果您有具体问题,请提出更具体的问题 :)