美文网首页
Spring事件机制

Spring事件机制

作者: 文景大大 | 来源:发表于2021-08-18 20:36 被阅读0次

    事件机制主要由三个部分组成:

    • 事件对象
    • 事件监听者
    • 事件源头

    其中它们之间的关系是,监听者会订阅事件源头,事件源头会发布事件对象。Java原生提供了事件机制,主要包含如下内容:

    • EventObject,对应事件对象,自定义的事件对象必须继承该类;
    • EventListener,对应事件监听者,处理监听到事件后的后续事情;
    • 事件源头只需要维护监听者,还有发布事件对象即可;

    下面给出一个基本的例子:

    public class OneEvent extends EventObject {
    
        private String eventMsg;
    
        public OneEvent(Object source, String eventMsg) {
            super(source);
            this.eventMsg = eventMsg;
        }
    
        public String getEventMsg() {
            return eventMsg;
        }
    }
    
    public class OneEventListener implements EventListener {
    
        public void handleEvent(OneEvent oneEvent){
            System.out.println("OneEvent happens, msg is : " + oneEvent.getEventMsg());
        }
    
    }
    
    public class OneEventSource {
    
        // 存储订阅者
        private Set<OneEventListener> listenerSet = new HashSet<>();
    
        public void addListener(OneEventListener listener){
            listenerSet.add(listener);
        }
    
        // 发布事件
        public void publishEvent(OneEvent event){
            for(OneEventListener listener : listenerSet){
                listener.handleEvent(event);
            }
        }
    }
    
    public class TestMain {
    
        public static void main(String[] args) {
            // 声明一个事件源
            OneEventSource oneEventSource = new OneEventSource();
            // 声明一个事件监听者
            OneEventListener listener = new OneEventListener();
            // 事件监听者订阅事件源
            oneEventSource.addListener(listener);
    
            // 事件源进行事件的发布
            oneEventSource.publishEvent(new OneEvent(oneEventSource, "one-event"));
        }
    }
    

    既然Java原生提供了事件机制,我们为什么还要使用Spring的事件机制呢?Java原生的事件机制有如下的缺点对开发者不友好:

    • 监听者订阅事件需要手动注册,比如oneEventSource.addListener(listener);
    • 事件源发生事件后,需要手动循环遍历所有监听者逐个通知;

    在Spring中,完全可以将如上两步进行自动化管理,其主要包含如下内容:

    • ApplicationEvent,对应事件对象,继承EventObject;
    • ApplicationListener,对应事件监听者,继承EventListener;
    • ApplicationEventPublisher,事件发布者,由它来进行事件的publish;
    • ApplicationEventPublisherAware,实现该接口的Bean会被Spring进行管理,且其中声明的ApplicationEventPublisher会被Spring自动设置;

    下面给一个具体的使用案例:

    public class SpringEvent extends ApplicationEvent {
    
        private String eventMsg;
    
        public SpringEvent(Object source, String eventMsg) {
            super(source);
            this.eventMsg = eventMsg;
        }
    
        public String getEventMsg(){
            return this.eventMsg;
        }
    }
    

    SpringEvent和Java原生事件案例中的OneEvent基本一致,只不过继承的父类不同而已。

    @Component
    public class SpringListener implements ApplicationListener<SpringEvent> {
    
        @Override
        public void onApplicationEvent(SpringEvent event) {
            System.out.println("SpringEvent happens, msg is : " + event.getEventMsg());
        }
    }
    

    监听者Listener必须要交给Spring进行管理,所以必须加上注解@Component,并且实现的接口泛型中带有该监听者需要监听的事件类型,由此,Spring来管理监听者和事件的绑定关系,以及事件发生时,通知所有监听者的工作。

    @RestController
    @RequestMapping("event")
    public class SpringEventPublisher implements ApplicationEventPublisherAware {
    
        private ApplicationEventPublisher applicationEventPublisher;
    
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
            this.applicationEventPublisher = applicationEventPublisher;
        }
    
        @GetMapping("/publish")
        public void publishEvent(String eventMsg){
            applicationEventPublisher.publishEvent(new SpringEvent(this,"SpringEvent"));
        }
    }
    

    最后,我们的事件发布者SpringEventPublisher也必须要交给Spring进行管理,因此加上注@RestController,同时对外提供Rest接口服务;

    同时,发布者需要实现ApplicationEventPublisherAware接口,目的是让Spring给我们自动设置ApplicationEventPublisher发布者,我们只需要调用发布方法即可。

    启动服务,访问接口localhost:8080/event/publish就会发现监听者打印了对应的内容。

    相关文章

      网友评论

          本文标题:Spring事件机制

          本文链接:https://www.haomeiwen.com/subject/zjqosltx.html