Spring事件解析

首先介绍Spring事件相关类的关系:

 

其中EventListener与EventObject均是Java SE的范畴,源码如下:

package java.util;

public interface EventListener {
}
package java.util;

public class EventObject implements java.io.Serializable {

    private static final long serialVersionUID = 5516075349620653480L;

    protected transient Object  source;

    public EventObject(Object source) {
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }

    public Object getSource() {
        return source;
    }

    public String toString() {
        return getClass().getName() + "[source=" + source + "]";
    }
}

 

Spring继承以上二者,可知Spring的事件实现机制也是基于观察者模式(Observer),除此之外,Spring提供了针对Bean的事件传播功能。

事件机制三元素:发布者、接收者、事件对象;接收者也可称为监听器。Spring中、通过分别继承Java SE中的EventListener和EventObject实现了接收者、事件对象。

package org.springframework.context;

import java.util.EventListener;

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    void onApplicationEvent(E event);

}
package org.springframework.context;

import java.util.EventObject;


public abstract class ApplicationEvent extends EventObject {

    private static final long serialVersionUID = 7099057708183571937L;

    private final long timestamp;

    public ApplicationEvent(Object source) {
        super(source);
        this.timestamp = System.currentTimeMillis();
    }

    public final long getTimestamp() {
        return this.timestamp;
    }

}

 

Java SE中并未提供事件发布者这一角色,在Spring中,则提供了ApplicationEventPublisher接口作为发布者,源码如下:

package org.springframework.context;

public interface ApplicationEventPublisher {

    void publishEvent(ApplicationEvent event);

    void publishEvent(Object event);

}

 

至此、Spring事件机制三大角色全部构建完成。下面通过案例解析,并进一步解说发布者,代码如下:

事件对象:

package com.charles.spring.event;

import org.springframework.context.ApplicationEvent;

public class HelloEvent extends ApplicationEvent{

    private static final long serialVersionUID = 1L;

    public HelloEvent(Object source) {
        super(source);
    }

}

接收者/监听器:

package com.charles.spring.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class HelloListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        
        if(event instanceof HelloEvent){
            System.out.println("Hello World");
        }
        
    }

}

Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-4.3.xsd ">

    <description>spring-configuration</description>

    <bean id="helloEvent" class="com.charles.spring.event.HelloEvent">
        <constructor-arg index="0" value="Hello" />
    </bean>
    <bean id="helloListener" class="com.charles.spring.event.HelloListener" />

</beans>

测试代码:

package com.charles.spring.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.charles.spring.event.HelloEvent;

public class TestEvent {
    
    @Test
    @SuppressWarnings("resource")
    public void testHelloEvent(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/spring-config.xml");
        HelloEvent helloEvent = (HelloEvent)applicationContext.getBean("helloEvent");
        applicationContext.publishEvent(helloEvent);
    }

}

运行结果:

至此、案例代码结束,也许你尚未看到发布者的实现在哪里,其实在文章开头的类图中就ApplicationEventPublisher的继承实现作了介绍,ApplicationContext接口继承了ApplicationEventPublisher,所以我们在测试代码中,直接使用ApplicationContext作为发布者进行发布。

 

posted @ 2017-07-25 16:31  ITACHY  阅读(308)  评论(0编辑  收藏  举报