Spring入门学习——使用应用事件进行通信

来源:互联网 发布:淘宝权限管理 编辑:程序博客网 时间:2024/06/11 20:21

在组件之间的典型通信模式中,发送者必须定位接收者,以便调用接收者之上的方法。在这种情况下,发送者组件必须了解接收者组件。这种通信直接而简单,但是发送者和接收者组件紧密耦合。

Spring的应用上下文支持基于事件的Bean间通信。在基于事件的通信模式中,发送者组件只要发布一个事件而不需要知道接收者。实际上,可以有多于一个接收者组件。而且,接收者不需要知道是谁发布了事件,可以同时监听不同的发送者的多个事件。这样,发送者和接收者组件是低耦合的。

在Spring中,所有事件类都必须扩展ApplicationEvent类。这样,任何Bean都可以调用应用事件发布者的publishEvent()方法,从而发布一个事件。对于监听某些事件的Bean来说,必须实现ApplicationListener接口,并在onApplicationEvent()方法中处理事件。实际上,Spring将通知所有事件的监听者,必须过滤事件。但是如果使用类属,Spring将只发布匹配类属参数的消息。

在之前博客使用到的购物例子和收银员出账例子中进行学习,无关核心代码省略


定义事件:

package com.cgy.springrecipes.shop;import java.util.Date;import org.springframework.context.ApplicationEvent;public class CheckoutEvent extends ApplicationEvent {    private double amount;    private Date time;    public CheckoutEvent(Object source, double amount, Date time) {        super(source);// 要调用父类构造函数,否则报错        this.amount = amount;        this.time = time;    }    public double getAmount() {        return amount;    }    public Date getTime() {        return time;    }}

发布事件:

package com.cgy.springrecipes.shop;import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.util.Date;import java.util.Locale;import org.springframework.context.ApplicationEventPublisher;import org.springframework.context.ApplicationEventPublisherAware;import org.springframework.context.MessageSource;import org.springframework.context.MessageSourceAware;/** * 用于购物车中产品的结账 * 在一个文本文件中记录每次结账的时间和数量 */public class Cashier implements StorageConfig,MessageSourceAware,ApplicationEventPublisherAware{    ......    private ApplicationEventPublisher applicationEventPublisher;    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {        this.applicationEventPublisher = applicationEventPublisher;    }    /**     * @param cart 购物车     * @throws IOException     */    public void checkout(ShoppingCart cart) throws IOException {        ......        CheckoutEvent event = new CheckoutEvent(this,total,new Date());        applicationEventPublisher.publishEvent(event);    }}

代码中的 ApplicationEventPublisherAware 是之前学习过的“感知容器”接口中的其中一个。同时发布事件类中需要定义一个 ApplicationEventPublisher 的引用,实现 ApplicationEventPublisherAware 接口需要覆盖一个 setApplicationEventPublisher() 方法


监听事件:

package com.cgy.springrecipes.shop;import java.util.Date;import org.springframework.context.ApplicationListener;public class CheckoutListener implements ApplicationListener<CheckoutEvent>{    public void onApplicationEvent(CheckoutEvent event) {        double amount = ((CheckoutEvent)event).getAmount();        Date time = ((CheckoutEvent)event).getTime();        System.out.println("Checkout event["+amount+","+time+"]");    }}

在定义事件,发布事件,监听事件后,还需要在应用上下文中注册监听器以监听所有事件。

<bean class="com.cgy.springrecipes.shop.CheckoutListener"/>

除了我们自身定义的事件外,应用上下文本身也会发布容器事件。

0 0
原创粉丝点击