欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring入门之事件处理

程序员文章站 2022-05-14 17:54:07
...

面向接口编程简述

面向接口编程,也就是非面向实现。它不能通过抽象类取代接口,因为:接口目的是抽象,抽象类目的是复用
同时还有一个好处: 接口是可以多实现的,类/抽象类只能单继承,所以使用接口可以非常容易扩展新功能(还可以实现所谓的mixin),类/抽象类办不到


Spring事件机制–事件驱动模型/观察者抽象

事件驱动模型也就是我们常说的观察者,或者发布-订阅模型;理解它的几个关键点:
1.首先是一种对象间的一对多的关系;最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方);

2.当目标发送改变(发布),观察者(订阅者)就可以接收到改变;

3.观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的),目标无需干涉;所以就松散耦合了它们之间的关系。
Spring事件驱动模型/观察者模型的结构图:

Spring入门之事件处理

Spring的事件

具体代表者是:ApplicationEvent
1、其继承自JDK的EventObject,JDK要求所有事件将继承它,并通过source得到事件源,比如我们的AWT事件体系也是继承自它;
2、系统默认提供了如下ApplicationEvent事件实现:
1.ContextStartedEvent:ApplicationContext启动后触发的事件;通过调用ConfigurableApplicationContext容器对象的start方法可以触发该事件

2.ContextStoppedEvent:ApplicationContext停止后触发的事件;通过调用ConfigurableApplicationContext容器对象的stop方法可以触发该事件

3.ContextRefreshedEvent:ApplicationContext初始化或刷新完成后触发的事件;(容器初始化完成后调用)

4.ContextClosedEvent:ApplicationContext关闭后触发的事件;(如web容器关闭时自动会触发spring容 器的关闭,如果是普通java应用,需要调用ctx.registerShutdownHook();注册虚拟机关闭时的钩子才行)

目标:事件发布者

具体代表者是:ApplicationEventPublisher及ApplicationEventMulticaster
ApplicationContext接口继承了ApplicationEventPublisher,并在 AbstractApplicationContext实现了具体代码,实际执行是委托给ApplicationEventMulticaster(可以 认为是多播):ApplicationContext都继承自AbstractApplicationContext,比如ClassPathXmlApplicationContext、FileSystemXmlApplication Context等,所以ApplicationContext自动拥有事件发布的功能
ApplicationContext自动到本地容器里找一个名字为”executor“的ApplicationEventMulticaster实现,如果 没有自己new一个SimpleApplicationEventMulticaster。
所以我们发送事件只需要通过ApplicationContext.publishEvent即可,没必要再创建自己的实现了。除非有必要。


Spring的监听器

具体代表者是:ApplicationListener;其继承自JDK的EventListener,JDK要求所有监听器将继承它,比如我们的AWT事件体系也是继承自它;其实现代码:
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {  
    void onApplicationEvent(E event);  
}  
从代码中可以看出,它只提供了一个onApplicationEvent事件处理方法,虽然这样实现起来就很简单,不过有时候还需要提供顺序触发监听器的操作,因此,Spring提供了另一个接口: SmartApplicationListener,它实现了Ordered接口,还可以方便我们去判断支持的事件类型。实现代码如:
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {  
        //如果实现支持该事件类型 那么返回true  
    boolean supportsEventType(Class<? extends ApplicationEvent> eventType);  

        //如果实现支持“目标”类型,那么返回true  
    boolean supportsSourceType(Class<?> sourceType);  

        //顺序,即监听器执行的顺序,值越小优先级越高  
        int getOrder();  
}  

Spring内置事件处理机制实例

//StartListener define
public class StartListener implements ApplicationListener<ContextStartedEvent> {

    @Override
    public void onApplicationEvent(ContextStartedEvent arg0) {

        System.out.println("application starting...");
    }

}


//stopListener define
public class StopedListener implements ApplicationListener<ContextStoppedEvent> {

    @Override
    public void onApplicationEvent(ContextStoppedEvent arg0) {

        System.out.println("context stopped..");
    }

}


//beans.xml配置
<!-- 注入事件监听器 -->
        <bean id="startEvent" class="org.spring.event.StartListener" />
        <bean id="stopEvent" class="org.spring.event.StopedListener" />


//测试主程序
public class TestMain {

    public static void main(String[] args){

        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        context.start();

        System.out.println("running...");

        context.stop();
    }
}


Spring自定义事件

首先定义一个自定义事件类PersonalEvent类,继承自ApplicationEvent
public class PersonalEvent extends ApplicationEvent {

    private static final long serialVersionUID = 1L;

    //初始化获取事件源
    public PersonalEvent(Object source) {
        super(source);
    }

}
然后定义事件处理器用于对事件进行相应的处理,该事件处理器继承自ApplicationListener
public class PersonalEventHnadler implements ApplicationListener<PersonalEvent> {


    @Override
    public void onApplicationEvent(PersonalEvent event) {

        System.out.println("event.name->"+event.toString());
    }

}
再定义一个发布类用于发布事件,该类继承自ApplicationEventPublisherAware,可以在该类中调用publishEvent方法来发布事件,也可以在主程序中直接调用ApplicationContext容器对象的publishEvent方法来发布事件
public class PersonalEventPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        // TODO Auto-generated method stub
        this.publisher = applicationEventPublisher;
    }

    public void publish(){
        PersonalEvent personalEvent = new PersonalEvent(this);
        publisher.publishEvent(personalEvent);
    }

}
主程序测试
public class TestMain {

    public static void main(String[] args){

        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        PersonalEventPublisher publisher = context.getBean("personalEventPublisher",PersonalEventPublisher.class);

        //publisher发布事件
        publisher.publish();

        //Ioc容器直接发布事件
        PersonalEvent personalEvent = new PersonalEvent();
        context.publishEvent(personalEvent);
    }
}

参考文档

Spring中实现自定义事件
Spring 中的自定义事件
spring事件机制