基于观察者模式,模拟Spring的事件监听器实现异步订阅消息

文章介绍了如何创建一个事件发布者类用于注册消费者并发布消息,使用Spring的注解管理Bean。事件发布采用异步处理,通过新建线程来执行消费者的方法。同时展示了消费者接口及其实现类,以及一个简单的测试用例来展示系统工作流程。
摘要由CSDN通过智能技术生成

备注:不想基于Spring,就将spring的注解去掉就行。只不过需要自己new对象。基于spring,要源码可以找我哟。

定义事件发布者:该类的作用主要用于注册消费者,发布消息。异步处理消息:因此需要新开线程去处理。

package com.apeli.design;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * subject
 *
 * @author liming
 * @date 2023 06 07
 */
@Component
public class MessagePublisher {

    /**
     * 消费者列表
     */
    private List<Consumer> consumerList;

    /**
     * 消息
     */
    private Event event;

    public MessagePublisher() {
        this.consumerList = new ArrayList<>();
    }


    /**
     * 发布事件
     *
     * @param event 事件
     */
    public void publishEvent(Event event) {
        this.event = event;
        notifyAllObserver(event);
    }

    /**
     * 注册消费者
     *
     * @param consumer 消费者
     */
    public void register(Consumer consumer) {
        consumerList.add(consumer);
    }

    /**
     * 通知所有观察者
     *
     * @param event 状态
     */
    private void notifyAllObserver(Event event) {
        consumerList.forEach(consumer -> {
            new Thread(() -> consumer.consumer(event)).start();
        });
    }

    @Data
    @AllArgsConstructor
    public static class Event<T> {
        private Integer eventId;

        private T eventContent;
    }
}

定义消费者: 定义事件发布器主要是为了在消费者被实例化时,自动加入事件发布器的consumerList中。这样做的好处是,如果我自定义的事件发布器和消费者都打上@compent的注解,在Spring初始化Bean时,事件监听器中会自动注册消费者。

package com.apeli.design;

/**
 * 观察者模式
 *
 * @author liming
 * @date 2023 06 07
 */
public abstract class Consumer {

    /**
     * 事件发布器
     */
    protected MessagePublisher messagePublisher;

    /**
     *消费事件
     * @param event 事件
     */
    public abstract void consumer(MessagePublisher.Event event);
}

实现类:

package com.apeli.design;

import lombok.SneakyThrows;
import org.springframework.stereotype.Component;


/**
 * 消费者
 *
 * @author liming
 * @date 2023 06 07
 */
@Component
public class OrderConsumer extends Consumer {

    public OrderConsumer(MessagePublisher messagePublisher) {
        this.messagePublisher = messagePublisher;
        messagePublisher.register(this);
    }

    @Override
    @SneakyThrows
    public void consumer(MessagePublisher.Event event) {
        Thread.sleep(1000);
        System.out.println("消费消息:"+event);
    }
}

测试:

package com.apeli;

import com.apeli.design.MessagePublisher;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class SourceApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SourceApplication.class);
        MessagePublisher messagePublisher = (MessagePublisher) context.getBean("messagePublisher");
        messagePublisher.publishEvent(new MessagePublisher.Event(10,"消息"));
        System.out.println("contine...");
    }
}

截图:
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值