Spring的事件驱动模型实战
本文介绍的是spring内置的基于ApplicationListener和ApplicationEvent的事件驱动模型:
需求场景:将用户登录成功后的相关信息封装成实体对象,由生产者采用异步的方式发送给消费者,消费者监听到消息后进行相应的处理并执行其他的业务逻辑。
spring应用系统中构建消息模型、实现消息的异步分发和业务模块的解耦合
步骤:
(1)创建用户登录成功后的事件实体类LoginEvent,该实体类继承ApplicationEvent并实现序列化接口:
package com.sswh.event;
import org.springframework.context.ApplicationEvent;
import java.io.Serializable;
/**
* @author sswh
* @since 2021/4/13
*/
public class LoginEvent extends ApplicationEvent implements Serializable {
private String userName;
private String loginTime;
private String ip;
public LoginEvent(Object source) {
super(source);
}
public LoginEvent(Object source, String userName, String loginTime, String id) {
super(source);
this.userName = userName;
this.loginTime = loginTime;
this.ip = id;
}
//toString(),和Getter、Setter
......
}
(2)编写监听消息的消费者Consumer类,该类实现ApplicationListener接口并绑定事件源LoginEvent:
package com.sswh.event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
/**
* @author sswh
* @since 2021/4/13
*/
@Component
@EnableAsync
public class Consumer implements ApplicationListener<LoginEvent> {
private static final Logger log = LoggerFactory.getLogger(Consumer.class);
@Async
@Override
public void onApplicationEvent(LoginEvent loginEvent) {
log.info("Spring 事件驱动模型——接收消息:{}", loginEvent);
//TODO 后续为实现自身的业务逻辑,比如写入数据库
}
}
(3)编写用户发送消息或产生事件的生产者Producer,其主要是通过内置的ApplicationEventPublisher组件实现消息的发送:
package com.sswh.event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author sswh
* @since 2021/4/13
*/
@Component
public class Publisher {
private static final Logger log = LoggerFactory.getLogger(Publisher.class);
@Autowired
private ApplicationEventPublisher publisher;
public void sendMsg() {
//构造用户登录成功后的实体消息
LoginEvent event = new LoginEvent(this, "debug", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "127.0.0.1");
//发送消息
publisher.publishEvent(event);
log.info("Spring事件驱动模型——发送消息:{}", event);
}
}
(4)测试:
package com.sswh;
import com.sswh.event.Publisher;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class EventTest {
@Autowired
private Publisher publisher;
@Test
public void test01() {
//调用发送消息的方法,产生消息
publisher.sendMsg();
}
}