spring 事件机制

spring的事件机制使用的是观察者模式
观察者模式学习http://www.runoob.com/design-pattern/observer-pattern.html
ApplicationEvent : 具体的事件对象,充当介质
这是一个抽象类,spring提供了几种实现 ApplicationContextEvent,ContextClosedEvent,ContextRefreshedEvent,ContextStartedEvent,ContextStoppedEvent和RequestHandledEvent

ApplicationEvent 源码如下:

public abstract class ApplicationEvent extends EventObject {

    /** use serialVersionUID from Spring 1.2 for interoperability */
    private static final long serialVersionUID = 7099057708183571937L;

    /** System time when the event happened */
    private final long timestamp;


    /**
     * Create a new ApplicationEvent.
     * @param source the component that published the event (never <code>null</code>)
     */
    public ApplicationEvent(Object source) {
        super(source);
        this.timestamp = System.currentTimeMillis();
    }


    /**
     * Return the system time in milliseconds when the event happened.
     */
    public final long getTimestamp() {
        return this.timestamp;
    }

}

ApplicationListener : 观察者,观察和处理具体事件
源码如下:

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    /**
     * Handle an application event.
     * @param event the event to respond to
     */
    void onApplicationEvent(E event);

}

ApplicationEventMulticaster : 观察者模式中的Subject ,负责管理观察者,发布事件

源码如下:

public interface ApplicationEventMulticaster {

    /**
     * Add a listener to be notified of all events.
     * @param listener the listener to add
     */
    void addApplicationListener(ApplicationListener listener);

    /**
     * Add a listener bean to be notified of all events.
     * @param listenerBeanName the name of the listener bean to add
     */
    void addApplicationListenerBean(String listenerBeanName);

    /**
     * Remove a listener from the notification list.
     * @param listener the listener to remove
     */
    void removeApplicationListener(ApplicationListener listener);

    /**
     * Remove a listener bean from the notification list.
     * @param listenerBeanName the name of the listener bean to add
     */
    void removeApplicationListenerBean(String listenerBeanName);

    /**
     * Remove all listeners registered with this multicaster.
     * <p>After a remove call, the multicaster will perform no action
     * on event notification until new listeners are being registered.
     */
    void removeAllListeners();

    /**
     * Multicast the given application event to appropriate listeners.
     * @param event the event to multicast
     */
    void multicastEvent(ApplicationEvent event);

}

ApplicationEventMulticaster spring中提供了默认的实现SimpleApplicationEventMulticaster,在spring的上下文application中有该类的bean,调用application的publishEvent方法时,就是直接调用该类的multicastEvent方法
publishEvent如下:

    public void publishEvent(ApplicationEvent event) {
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }
        getApplicationEventMulticaster().multicastEvent(event);
        if (this.parent != null) {
            this.parent.publishEvent(event);
        }
    }

ApplicationEventMulticaster 的multicastEvent会一次调用注册的观察者的onApplicationEvent方法
multicastEvent实现如下:

    public void multicastEvent(final ApplicationEvent event) {
        for (final ApplicationListener listener : getApplicationListeners(event)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    @SuppressWarnings("unchecked")
                    public void run() {
                        listener.onApplicationEvent(event);
                    }
                });
            }
            else {
                listener.onApplicationEvent(event);
            }
        }
    }

使用spring事件机制的例子 邮件发送提示
1.定义事件

public class MailSendEvent extends ApplicationEvent {

    public MailSendEvent(Object source, String fromAddress, String toAddress) {
        super(source);
        this.fromAddress = fromAddress;
        this.toAddress = toAddress;
    }

    private static final long serialVersionUID = 1L;

    private String fromAddress;
    private String toAddress;

    public String getFromAddress() {
        return fromAddress;
    }

    public void setFromAddress(String fromAddress) {
        this.fromAddress = fromAddress;
    }

    public String getToAddress() {
        return toAddress;
    }

    public void setToAddress(String toAddress) {
        this.toAddress = toAddress;
    }

    @Override
    public String toString() {
        return fromAddress + " Send Mail to " + toAddress;
    }

}

2.定义观察者


public class MailSendEventListener implements ApplicationListener<MailSendEvent> {

    public void onApplicationEvent(MailSendEvent event) {
        System.out.println("发生一个邮件发送的事件:" + event);
    }

}

3.定义触发事件发生的地方,即发送邮件的地方

public class MailBean implements ApplicationContextAware {

    private String fromAddress;
    private String toAddress;

    ApplicationContext applicationContext;

    public MailBean(String fromAddress, String toAddress) {
        this.fromAddress = fromAddress;
        this.toAddress = toAddress;
    }

    public void sendMail() {
        System.out.println(fromAddress + " Send Mail to " + toAddress);
        MailSendEvent event = new MailSendEvent(applicationContext, fromAddress, toAddress);
        applicationContext.publishEvent(event);

    }

    public String getFromAddress() {
        return fromAddress;
    }

    public void setFromAddress(String fromAddress) {
        this.fromAddress = fromAddress;
    }

    public String getToAddress() {
        return toAddress;
    }

    public void setToAddress(String toAddress) {
        this.toAddress = toAddress;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

    }

}

4.配置文件

    <bean class="com.yang.spring.event.MailSendEventListener" />


    <bean id="mailTest" class="com.yang.spring.event.MailBean" init-method="sendMail">
        <constructor-arg index="0" value="ttt"></constructor-arg>
        <constructor-arg index="1" value="yyy"></constructor-arg>
    </bean>

5.测试

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

6.测试结果

ttt Send Mail to yyy
发生一个邮件发送的事件:ttt Send Mail to yyy
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值