今天,我们以一个非常简单的场景为例:下订单将其存储并发送有关该订单的电子邮件:
@Service
class OrderService @Autowired() (orderDao: OrderDao, mailNotifier: OrderMailNotifier) {
@Transactional
def placeOrder(order: Order) {
orderDao save order
mailNotifier sendMail order
}
}
到目前为止,一切都很好,但是电子邮件功能与下订单无关。 这只是一种分散注意力的副作用,而不是业务逻辑的一部分。 此外,发送电子邮件不必要地延长了交易时间并引入了延迟。 因此,我们决定使用事件将这两个动作分离。 为简单起见,我将利用Spring内置的自定义事件,但是我们的讨论与JMS或其他生产者-消费者库/队列同样重要。
case class OrderPlacedEvent(order: Order) extends ApplicationEvent
@Service
class OrderService @Autowired() (orderDao: OrderDao, eventPublisher: ApplicationEventPublisher) {
@Transactional
def placeOrder(order: Order) {
orderDao save order
eventPublisher publishEvent OrderPlacedEvent(order)
}
}
如您所见,我们直接发送OrderPlacedEvent
包装新创建的订单,而不是直接访问OrderMailNotifier
bean。 发送事件需要ApplicationEventPublisher
。 当然,我们还必须实现客户端接收消息:
@Service
class OrderMailNotifier extends ApplicationListener[OrderPlacedEvent] {
def onApplicationEvent(event: OrderPlacedEvent) {
//sending e-mail...
}
}
ApplicationListener[OrderPlacedEvent]
指示我们感兴趣的事件类型。此方法有效,但是默认情况下,Spring ApplicationEvent
是同步的,这意味着publishEvent()
实际上正在阻塞。 知道Springÿ