从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架

这篇具有很好参考价值的文章主要介绍了从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.测试案例

定义一个事件

package com.example.demo.event;
import org.springframework.context.ApplicationEvent;

public class MyEvent extends ApplicationEvent {
    public MyEvent(Object source) {
        super(source);
    }
}

定义两个listener

package com.example.demo.event;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class Listener1 implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        String source = (String) event.getSource();
        System.out.println(this.getClass().getName() + ":" + source);
    }
}
package com.example.demo.event;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class Listener2 implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        String source = (String) event.getSource();
        System.out.println(this.getClass().getName() + ":" + source);
    }
}

注入spring容器里的ApplicationEventPublisher对象,发布事件

package com.example.demo;


import com.example.demo.event.MyEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class EventPublisherTest {

    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Test
    public void test() {
        eventPublisher.publishEvent(new MyEvent("xxx"));
    }
}

2.DEBUG源码分析

eventPublisher.publishEvent(new MyEvent("xxx"));进去很容易就能找到,可以发现SimpleApplicationEventMulticaster这个事件发布对象持有所有listenter对象及MyEvent对象,
事件发布过程其实就是遍历拿到每个listener对象并调用它自己的onApplicationEvent()方法

SimpleApplicationEventMulticaster类的主要方法:

  • addApplicationListener(ApplicationListener<?> listener) :
  • addApplicationListenerBean(String listenerBeanName):
  • removeApplicationListener(ApplicationListener<?> listener):
  • removeApplicationListenerBean(String listenerBeanName):
  • multicastEvent(ApplicationEvent event):广播事件;
  • multicastEvent(ApplicationEvent event, @Nullable
    ResolvableType eventType):广播事件,指定事件的source类型。

从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架,观察者模式,java,spring event

3. 异步监听

从上图断点可以看到ApplicationEventMulticaster对象持有有taskExecutor字段为null,导致没有异步执行所有监听器。这里需要想办法这个字段设置线程池即可:
springboot默认会配置一个ThreadPoolTaskExecutor对象在容器里,这里把它拿出来设置给ApplicationEventMulticaster对象即可

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;


/**
 * @author Administrator
 */
@SpringBootApplication
public class DemoApplication {

    @Resource
    private SimpleApplicationEventMulticaster eventMulticaster;
    @Resource
    private ThreadPoolTaskExecutor executor;

    @PostConstruct
    public void setEventExecutor() {
        eventMulticaster.setTaskExecutor(executor);
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

4.ApplicationListener子接口

还可以实现子类的getOrder方法可以实现多个监听器排序;实现supportsEventType,supportsSourceType可以实现按过滤Class过来或按事件源Source的Class过滤
从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架,观察者模式,java,spring event

5. 注解支持

这里不通过实现接口来实现监听,顺序排序,按事件类型过滤监听,采用更方便的注解实现,且一个类中就可以实现多个监听

package com.example.demo.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
public class Listener3 {

    @Order(Integer.MIN_VALUE) // 优先级最高
    @EventListener(MyEvent.class)  // 只监听指定类型的事件
    public void onApplicationEvent(ApplicationEvent event) {
        MyEvent myEvent = (MyEvent) event;
        System.out.println(this.getClass().getName() + ":" + myEvent.getSource());
    }
}

6. 基于观察者模式高仿spring事件监听

6.1 先定义自定义一个事件

Java中已定义观察者模式事件及监听器顶级接口

package com.example.demo.javanativeevent;

import java.util.EventObject;

public class MyJavaNativeEvent extends EventObject {

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

6.2 定义两个监听器

因为Java提供的EventListener无具体监听方法,且无合适的子接口,故这里自定义一个类似spirng的子接口NativeEventListener。这样后续事件发布就是遍历这种类型接口并调用onApplicationEvent()方法文章来源地址https://www.toymoban.com/news/detail-655887.html

package com.example.demo.javanativeevent;

import java.util.EventListener;
import java.util.EventObject;

public interface NativeEventListener extends EventListener {
    void onApplicationEvent(EventObject event);
}
package com.example.demo.javanativeevent;

import java.util.EventObject;


public class JavaNativeListener1 implements NativeEventListener {

    @Override
    public void onApplicationEvent(EventObject event){
        String source = (String)event.getSource();
        System.out.println(this.getClass().getName()+":"+source);
    }
}

6.3 定义一个持有所有监听器的对象,类似spring的SimpleApplicationEventMulticaster

package com.example.demo.javanativeevent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.EventObject;
import java.util.List;

/**
 * TODO
 *
 * @author majun
 * @version 1.0
 * @since 2023-08-13 18:50
 */
public class SimpleJavaNativeEventMulticaster {

    public List<NativeEventListener> eventListeners= Collections.synchronizedList(new ArrayList<>(8));


    public void addListener(NativeEventListener listener){
        this.eventListeners.add(listener);
    }
    public void multicastEvent(EventObject eventObject){
        eventListeners.stream().parallel().forEach(listener -> {
           listener.onApplicationEvent(eventObject);
        });
    }
}

6.4 事件发布测试

package com.example.demo.javanativeevent;

/**
 * TODO
 *
 * @author majun
 * @version 1.0
 * @since 2023-08-13 19:01
 */
public class EventPublishTest {


    public static void main(String[] args) {
        // 注册两个listener,这是spirng把这个过程隐藏在spring容器初始化过程中了
        SimpleJavaNativeEventMulticaster eventMulticaster = new SimpleJavaNativeEventMulticaster();
        eventMulticaster.addListener(new JavaNativeListener1());
        eventMulticaster.addListener(new JavaNativeListener2());
        // 发布事件
        eventMulticaster.multicastEvent(new MyJavaNativeEvent("yyyy"));
    }
}

到了这里,关于从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Unity] No.3 EventManager事件管理 与 观察者模式

    前文讲到了InputManager,在其后需要一个事件的管理者用于调度任务的执行,包括: ①查看发生了什么事; ②出事后看看都需要通知谁干什么事; 以上两个内容就对应了EventManager中关键的 监听 和 回调 ,而在讲EventManager之前还需要知道,它是符合观察者这一模式的。 此处不

    2024年02月08日
    浏览(46)
  • 深入理解设计模式-行为型之观察者

    观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种 一对多的依赖关系 ,让 多个观察者对象 同时监听一个 主题对象 ,当 主题对象 发生 变化 时,所有依赖于它的 观察者 对象都会得到 通知并更新。 在观察者模式中,有两个主要角色: Subject(主题):维护

    2024年02月12日
    浏览(50)
  • Spring Event 观察者模式, 业务解耦神器

    观察者模式在实际开发过程中是非常常见的一种设计模式。 Spring Event的原理就是观察者模式,只不过有Spring的加持,让我们更加方便的使用这一设计模式。 概念 : 观察者模式又叫发布-订阅模式。 发布指的是当目标对象的状态改变时,它就向它所有的观察者对象发布 状态更

    2024年02月08日
    浏览(64)
  • 性能优化之懒加载 - 基于观察者模式和单例模式的实现

            在前端性能优化中,关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时,才去请求加载对应的图像。 原理也很简单,通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org),观察“哪个元素和视口交叉”,从而进行懒加载。

    2024年02月05日
    浏览(38)
  • 【C++ 观察者模式 思想理解】C++中的观察者模式:松耦合设计与动态交互的艺术,合理使用智能指针观察者

    在进入技术细节之前,理解观察者模式(Observer Pattern)的基本概念和它在现代编程中的重要性是至关重要的。 观察者模式是一种设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在C++中,这个

    2024年01月24日
    浏览(56)
  • 观察者模式(上):详解各种应用场景下观察者模式的不同实现方式

            从今天起,我们开始学习行为型设计模式。我们知道,创建型设计模式主要解决“对象的创建”问题,结构型设计模式主要解决“类或对象的组合或组装”问题,那行为型设计模式主要解决的就是“ 类或对象之间的交互 ”问题。 原理及应用场景剖析 在对象之间

    2024年02月16日
    浏览(57)
  • 观察者设计模式

    行为型模式(Behavioral Patterns):这类模式主要关注对象之间的通信。它们 分别是: 职责链模式(Chain of Responsibility) 命令模式(Command) 解释器模式(Interpreter) 迭代器模式(Iterator) 中介者模式(Mediator) 备忘录模式(Memento) 观察者模式(Observer) 状态模式(State) 策略

    2024年01月24日
    浏览(51)
  • 设计模式-观察者

    观察者模式是一种广泛应用于软件开发中的行为设计模式,尤其是在面向对象编程(OOP)中。该模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新 在观察者模式中,存在两个主要角色: 主题(Subject) 或 被

    2024年01月22日
    浏览(48)
  • 观察者模式(Observer)

    观察着模式是一种行为设计模式,可以用来定义对象间的一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。 观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者

    2024年02月14日
    浏览(39)
  • 观察者模式(Observer)

    事件订阅者者(Event-Subscriber) 监听者(Listener) 观察者 是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个“观察”该对象的其他对象。 1. 问题 假如你有两种类型的对象 :“顾客”和“商店”。顾客对某个特定品牌的产品非常感兴趣(例如最

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包