首页 > 其他分享 >Spring 中的发布-订阅模式

Spring 中的发布-订阅模式

时间:2024-04-18 22:34:39浏览次数:16  
标签:username 订阅 Spring 模式 事件 发布者 public

发布订阅模式是怎样的?

现在市面上流行的很多消息中间件就是采用的该种模式,这种模式 在实际业务中 将 事件发布者(Publisher) 与 事件订阅者 (Subscriber)通过额外的事件通道(Event Channel)来解耦,其基本原理与先前提到的观察者模式有些许类似,但发布订阅模式额外存在了Event Channel 的概念,也因此解决了 主题(Subject)和 Observer(观察者)之间的耦合,发布者和订阅者就交互细节上不再需要相互关联,下图可以看到两种模式之间的区别。

在 Spring 中的实际应用

在Spring框架中,发布-订阅模式是通过事件驱动的方式实现的,用于解耦应用程序中的组件。Spring的事件机制允许应用程序中的各个部分以松散耦合的方式进行通信,这种方式在日常编码中最适合应对一些需要状态机的业务模型, 下面就来讲下 在 Spring 中的发布订阅涉及到的概念

  • 事件(Event):事件是应用程序中的状态变化或动作,对应于某个特定的行为或状态。在Spring中,事件通常是一个POJO(Plain Old Java Object)类,它包含了与该事件相关的信息。
  • 事件发布者(Event Publisher):事件发布者是负责发布事件的组件。在Spring中,ApplicationContext(应用程序上下文)充当了事件发布者的角色。通过ApplicationContext,应用程序可以发布事件,并将其传递给已注册的事件监听器。
  • 事件订阅者(Event Subscriber):事件订阅者是负责处理特定类型事件的组件。在Spring中,事件订阅者通常是实现了ApplicationListener接口的类,用于监听并处理发布的事件。
  • 事件推送(ApplicationEventPublisher):事件推送是指通过ApplicationEventPublisher接口在Spring中发布事件的过程。这个接口可以在ApplicationContext中使用,用于向已注册的监听器广播事件的发生。

设计步骤

  1. 定义事件类:首先,定义应用中的各种事件,这些事件可以是任何与应用状态变化或行为相关的事情。事件通常是简单的POJO类。
  2. 定义发布者:创建事件发布者(Publisher)组件,它负责发布事件。在Spring中,你可以使用ApplicationEventPublisher接口或者直接在Bean方法上标注@EventListener注解来实现。
  3. 定义订阅者:创建事件订阅者(Subscriber)组件,它负责订阅感兴趣的事件并对事件做出响应。在Spring中,你可以定义实现ApplicationListener接口的类来作为事件监听器,或者使用@EventListener注解在方法上订阅事件。
  4. 触发事件:在适当的时候,通过发布者发布事件。一旦事件被发布,所有已经注册的订阅者将会收到事件通知并执行相应的逻辑。

这里会以简单的 用户注册的场景来介绍下 Spring ApplicationEventPublisher 的使用方式

定义事件类UserRegisteredEvent

import org.springframework.context.ApplicationEvent;

public class UserRegisteredEvent extends ApplicationEvent {
    private final String username;

    public UserRegisteredEvent(Object source, String username) {
        super(source);
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}



创建UserRegistrationService服务,负责注册新用户并发布事件

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class UserRegistrationService {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void registerUser(String username) {
        // 注册新用户逻辑
        // ...

        // 发布用户注册事件,这里使用 eventPublisher 将 预先定义好的事件交由 Spring 的Event Channel 管理
        eventPublisher.publishEvent(new UserRegisteredEvent(this, username));
    }
}

创建UserNotificationService服务,订阅UserRegisteredEvent事件并发送通知
@Service
public class UserNotificationService {

    @EventListener
    public void handleUserRegisteredEvent(UserRegisteredEvent event) {
        // 处理用户注册事件,例如发送通知
        String username = event.getUsername();
        System.out.println("Notification sent for user: " + username);
    }
}

创建 Spring 启动类
@SpringBootApplication
@RequiredArgsConstructor
public class Application implements CommandLineRunner {

    private  final UserRegistrationService userRegistrationService;

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setWebApplicationType(WebApplicationType.NONE);
        app.run(args);
    }

    @Override
    public void run(String... args) {
        // 在启动时注册新用户
        userRegistrationService.registerUser("peng");
    }
}

最后程序的输出结果 如下所示:

Notification sent for user: peng

案例中的代码已发布在 github仓库 , 路径为package com.github.meeting.demo.pattern.pubsub;.

标签:username,订阅,Spring,模式,事件,发布者,public
From: https://www.cnblogs.com/pengpengon/p/18144663

相关文章

  • Spring Security快速入门
    使用SpringBoot+SpringSecurity整合,先定义一个空项目,主要为项目里面各个模块提供依赖,空项目依赖如下:<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.18</version>......
  • java静态代理模式
    通过模拟租房来展现静态代理模式租房接口//租房publicinterfaceRent{publicvoidrent();}被代理的真实角色房东//房东publicclassHostimplementsRent{@Overridepublicvoidrent(){System.out.println("房东要出租房租");}}......
  • SpringBoot 3.1.10 整合Mybatis-plus(快速学会)
    一、简介1、什么是Mybatis-plus?Mybatis-Plus(简称MP)是一个Mybatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。官网:https://baomidou.com/2、Mybatis-plus特性无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动......
  • springcloud alibaba gateway网关鉴权
    登录鉴权:在gateway网关中实现全局过滤器GlobalFilter以及拦截器的顺序Ordered,在nacos中配置好需要放行的路径(如登录/login),获取请求头中的用户id,组装reids的key,来redis中存放的value,即token,再获取请求头中的token来跟redis中的value值进行比对,一致则放行,否则抛出异常。核心代码如......
  • SpringCloud(七.4)ES(elasticsearch)-- DSL查询语法
    DSL查询语法 1、查询所有以下是简写和全写 总结:  2、全文检索查询(match)全文检索查询,会对用户输入内容分词,常用于搜索框搜索: 回顾在 SpringCloud(七.3)ES(elasticsearch)--RestClient操作 中创建索引时添加的all字段,以及字段拷贝copy_to。这里all字段就派上了用......
  • Spring boot中使用groovy
    groovy是当做一个脚本来用的,也可以从数据库加载代码做一些动态数据处理。搭建一个springboot环境,pom.xml中编辑器和jar包,springboot是2.1.6.RELEASE<dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.4.7</vers......
  • 【python】使用r+模式先读后写和先写后读的区别
    最近学习python时,发现r+(读写)模式先读和先写,写入的位置不一致,经过测试发现:1、先写后读,写从文件开头开始写(覆盖原文),读从写入末尾开始读;2、先读后写,读从文件开头开始读,写从文件末尾开始写。点击查看代码'''test.txt#####随便写点啥######'''#先写后读withopen('test.txt......
  • java桥接模式案例
    桥接模式(BridgePattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。在桥接模式中,抽象类和它的实现类之间使用组合/聚合关系,而不是继承关系。这样,客户端代码可以针对抽象编程,而实现细节则可以在运行时动态地指定。场景:假设我们要设计一个图形绘制系统......
  • benchmarksql压测lightdb的oracle模式
    一、编译安装BenchMarkSQL1.下载源码,输入ant编译。确保已经安装配置JDK环境,BenchMarkSQL是Java开发的。cdbenchmarksql/benchmarksql]$ant二、创建BenchMarkSQL测试数据库和角色[lightdb@linuxtestba65~]$ltsqlltsql(13.8-23.4)compatibletype:postgresqlType"......
  • 23种设计模式彩图-设计模式之禅
    《TheZenofDesignPatterns》—《设计模式之禅》书中的23种设计模式彩图:......