Spring系列之ApplicationEvent事件驱动模型

1 : 什么是Sping的事件

Spring的事件(ApplicationEvent)是为了提供Spring中对象(Bean)与对象之间的消息通信支持,也就是当一个bean处理完一个任务之后,想要另外一个bean知道,并能做出相应的处理,这个时候我们就需要另外一个bean监听到这个bean的消息。

2:业务场景

我们在处理完一段业务逻辑后,要给C端用户一个通知,很多地方都需要进行通知,每次new对象insert很麻烦,我们就可以用这个事件模型进行发布,在监听逻辑中处理,使我们代码之间的耦合度降低 提高效率。

3:怎么做

sping的事件需要遵从以下原则

①:自定义事件 继承ApplicationEvent

package com.dubug.middleware.entity;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;

import java.io.Serializable;
import java.util.Date;

@ToString
@Getter
@Setter
public class DbPushMessage extends ApplicationEvent implements Serializable {
    private String id;

    private String userId;

    private String messageType;

    private String explain;

    private Date pushTime;

    public DbPushMessage(Object source, String id, String userId, String messageType, String explain, Date pushTime) {
        super(source);
        this.id = id;
        this.userId = userId;
        this.messageType = messageType;
        this.explain = explain;
        this.pushTime = pushTime;
    }
}

② : 事件监听器

package com.dubug.middleware.listener;

import com.dubug.middleware.entity.DbPushMessage;
import com.dubug.middleware.mapper.DbPushMessageMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
/**
 * @Description
 * @Author 事件监听器 监听 DbPushMessage
 *         1: 实现 ApplicationListener 接口 并指定监听的bean
 *         2:实现 onApplicationEvent 方法 对消息进行处理
 * @Version V1.0.0
 * @Date 2021/6/9 0009
 */
@Slf4j
@Component
public class PushMessageListener implements ApplicationListener<DbPushMessage> {
  @Autowired
  private DbPushMessageMapper dbPushMessageMapper;

  @Override
  public void onApplicationEvent(DbPushMessage event) {
    Assert.notNull(event);
    log.info("监听到了事件:{}",event);
    dbPushMessageMapper.insert(event); //保存到数据库
  }
}

③: 事件发布类

package com.dubug.middleware.push;

import com.dubug.middleware.entity.DbPushMessage;
import com.dubug.middleware.util.IdGeneratorRegistry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Description
 * @Author 事件发布类
 *        1:注入ApplicationContext 用来发布事件
 *        2:使用 ApplicationContext 的publishEvent 方法来发布
 *
 * @Version V1.0.0
 * @Date 2021/6/9 0009
 */
 @Slf4j
@Component
public class PushMessagePush {
  @Autowired
  private ApplicationContext applicationContext;

  public void publish(String userId,String messageType,String explain){
    log.info("发布了事件{}",dbPushMessage);
    DbPushMessage dbPushMessage = new DbPushMessage(this,IdGeneratorRegistry.getId(),userId,messageType,explain,new Date());
    applicationContext.publishEvent(dbPushMessage);
  }

}

④: SpringBoot单元测试

package com.dubug.middleware.messageTest;

import com.dubug.middleware.applicationTest.ApplicationTest;
import com.dubug.middleware.push.PushMessagePush;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description
 * @Author 单元测试
 * @Version V1.0.0
 * @Date 2021/6/9 0009
 */
public class MessageTest extends ApplicationTest {
  @Autowired
  private PushMessagePush pushMessagePush;

  Map<String,String> beforeBean = new HashMap<>();
  @Before
  public void beforeBean(){
    beforeBean.put("1","tom");
    beforeBean.put("2","any");
  }

  @Test
  public void testPush(){
    pushMessagePush.publish(beforeBean.get("1"),"system_message","测试消息模型发布");
  }
}

看下运行结果
可以看到控制台已经打印出了结果
看下数据库

总结

 Spring的事件驱动模型可以帮我们更好的处理bean与bean直接的链接,同时也帮助我们降低了业务之间的耦合度,使我们更专注于业务代码的开发。

解决问题的过程是令人痛苦的,但是之后便是无比的成就感

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挚爱妲己~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值