前言
本节内容我们主要介绍一下springboot自定义事件的发布与订阅功能,一些特定应用场景下使用自定义事件发布功能,能大大降低我们代码的耦合性,使得我们应用程序的扩展更加方便。就本身而言,springboot的事件机制是通过观察者设计模式实现。通过ApplicationListener事件监听器实现事件的发布与订阅。我们以登录场景为例,假如用户登录之后,需要发送登录通知、发送邮件通知、发送签到通知,如果按照常规做法,我们可以顺序执行以上操作,但是使用springboot的事件机制,我们可以发布一个登录的事件消息,然后各自去消费登录这个事件消息,这样达到业务解耦的效果。
正文
①创建一个事件发布器,用于发送自定义的消息事件
- 实现代码:通过实现ApplicationEventPublisherAware 接口
package com.yundi.isbc.event.publish;import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component;@Component public class MyApplicationEventPublisherAware implements ApplicationEventPublisherAware {private ApplicationEventPublisher applicationEventPublisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}/*** 消息事件发布* @param applicationEvent*/public void publishEvent(ApplicationEvent applicationEvent) {applicationEventPublisher.publishEvent(applicationEvent);} }
②创建一个登录的自定义消息事件
- 实现代码:通过继承ApplicationEvent事件实现自定义消息事件
package com.yundi.isbc.event.publish;import com.yundi.isbc.entity.User; import org.springframework.context.ApplicationEvent;public class LoginApplicationEvent extends ApplicationEvent {public LoginApplicationEvent(User user) {super(user);} }
③创建一个用户实体类,用于数据的传输
- 实现代码
package com.yundi.isbc.entity;import lombok.Data; import lombok.experimental.Accessors;@Accessors(chain = true) @Data public class User {/*** 用户名*/private String username;/*** 密码*/private String password; }
④创建一个控制器LoginController,用于登录业务处理,并发布登录事件
- 实现代码
package com.yundi.isbc.controller;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import com.yundi.isbc.event.publish.MyApplicationEventPublisherAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/index") public class LoginController {@Autowiredprivate MyApplicationEventPublisherAware myApplicationEventPublisherAware;@GetMapping("login")public String login() {//发布登录事件myApplicationEventPublisherAware.publishEvent(new LoginApplicationEvent(new User().setUsername("xiaoming").setPassword("123456")));//todo 主流程业务处理return "ok";}}
- 代码说明
⑤ 通过实现ApplicationListener接口,实现登录通知消息的消费,并做相关的业务处理
- 实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Service;@Service public class LoginNotifyListen implements ApplicationListener<LoginApplicationEvent> {public void accumulateLogin(User user) {System.out.println("=======登录业务======" + user);}@Overridepublic void onApplicationEvent(LoginApplicationEvent event) {System.out.println("===============收到登录通知事件===================");User user = (User) event.getSource();accumulateLogin(user);} }
⑥通过@EventListener方式订阅消息,实现邮件业务处理,该种方式更加灵活,不用实现ApplicationListener接口
- 实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service;@Service public class MailNotifyListen {public void mailNotify(User user) {System.out.println("=======邮件业务======" + user);}@EventListenerpublic void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {System.out.println("===============收到登录通知事件===================");User user = (User) loginApplicationEvent.getSource();mailNotify(user);} }
⑦通过@EventListener方式订阅消息,实现签到业务处理
-实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service;@Service public class SignNotifyListen {public void signNotify(User user) {System.out.println("=======签到业务======" + user);}@EventListenerpublic void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {System.out.println("===============收到登录通知事件===================");User user = (User) loginApplicationEvent.getSource();signNotify(user);} }
⑧验证结果,访问登录接口,查看控制台,所有订阅事件的业务都能正常订阅消费
结语
关于springboot自定义事件的发布和订阅的内容到这里就结束了,我们下期见。。。。。。