Spring入门之事件处理

本文深入探讨Spring框架中的事件机制,包括面向接口编程的概念、事件驱动模型的原理与应用,以及如何利用Spring内置机制实现自定义事件。介绍了Spring事件的具体类型及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


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

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

3.观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的),目标无需干涉;所以就松散耦合了它们之间的关系。
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事件机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值