业务需求:
用户注册成功之后,系统会给用户发放优惠券,发送邮件,发送短信等操作。
作为开发人员,很容易写出如下代码:
/** * 用户注册逻辑 * * @author Lynch */ @GetMapping("/register") public String register(String username) { // 注册 userService.register(username); // 发送邮件 emailService.sendEmail(username); // 发送短信 smsService.sendEmail(username); // 发放优惠券 couponService.addCoupon(username); return "注册成功!"; }
这样写会有什么问题?
1. 方法调用时,同步阻塞导致响应变慢,需要异步非阻塞的解决方案。
2. 注册接口此时做的事情:注册,发邮件,发短信,发优惠券,违反单一职责的原则。当然,如果后续没有拓展和修改的需求,这样子倒可以接受。
3. 如果后续注册的需求频繁变更,相应就需要频繁变更register方法,违反了开闭原则。
我们采用Spring事件监听机制解决以上存在的问题。
Spring事件监听机制概述
SpringBoot中事件监听机制则通过发布-订阅实现,主要包括以下三部分:
1. 事件 ApplicationEvent,继承JDK的EventObject,可自定义事件。
2. 事件发布者 ApplicationEventPublisher,负责事件发布
3. 事件监听者 ApplicationListener,继承JDK的EventListener,负责监听指定的事件
我们通过SpringBoot的方式,能够很容易实现事件监听,接下来我们实现下上面的案例:
一、定义注册事件——UserRegisterEvent
package cn.itcast.user.demo.event; import org.springframework.context.ApplicationEvent; /** * 定义注册事件 * * @author Lynch */ public class UserRegisterEvent extends ApplicationEvent { private String username; public UserRegisterEvent(Object source) { super(source); } public UserRegisterEvent(Object source, String username) { super(source); this.username = username; } public String getUsername() { return username; } }
二、注解方式 @EventListener定义监听器——CouponService
package cn.itcast.user.demo.event; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; /** * 监听用户注册事件,执行发放优惠券逻辑 * * @author Lynch * */ @Service @Slf4j public class CouponService { @EventListener public void addCoupon(UserRegisterEvent event) { log.info("给用户[{}]发放优惠券", event.getUsername()); } }
三、注解方式 @EventListener定义监听器——SmsService
package cn.itcast.user.demo.event; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; /** * 监听用户注册事件,异步执行发送短信逻辑 * * @author Lynch * */ @Service @Slf4j public class SmsService implements ApplicationListener<UserRegisterEvent> { @Override @Async("taskExecutor") public void onApplicationEvent(UserRegisterEvent event) { log.info("给用户[{}]发送短信", event.getUsername()); } }
四、实现ApplicationListener的方式定义监听器——EmailService
package cn.itcast.user.demo.event; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; /** * 监听用户注册事件,异步执行发送邮件逻辑 * * @author Lynch * */ @Service @Slf4j public class EmailService implements ApplicationListener<UserRegisterEvent> { @Override @Async("taskExecutor") public void onApplicationEvent(UserRegisterEvent event) { log.info("给用户[{}]发送邮件", event.getUsername()); } }
五、注册事件发布者——UserServiceImpl
package cn.itcast.user.demo.event; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; /** * 注册事件发布者 * * @author Lynch * */ @Service @Slf4j public class UserServiceImpl implements ApplicationEventPublisherAware { // 注入事件发布者 private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } /** * 发布事件 */ public void register(String username) { log.info("执行用户[{}]的注册逻辑", username); applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username)); } }
六、单元测试——UserServiceImplTest
package cn.itcast.user.service; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import cn.itcast.user.BaseTest; import cn.itcast.user.demo.event.UserServiceImpl; public class UserServiceImplTest extends BaseTest { @Autowired private UserServiceImpl userServiceImpl; @Test public void register() { userServiceImpl.register("张三"); } }
运行结果如下:
11-17 14:39:49:520 INFO 20696 --- [ main] c.i.user.demo.event.UserServiceImpl : 执行用户[张三]的注册逻辑 11-17 14:39:49:522 INFO 20696 --- [ main] cn.itcast.user.demo.event.CouponService : 给用户[张三]发放优惠券 11-17 14:39:49:533 INFO 20696 --- [viceExecutor -1] cn.itcast.user.demo.event.EmailService : 给用户[张三]发送邮件 11-17 14:39:49:534 INFO 20696 --- [viceExecutor -2] cn.itcast.user.demo.event.SmsService : 给用户[张三]发送短信
标签:username,SpringBoot,监听,springframework,public,详解,org,import,event From: https://www.cnblogs.com/linjiqin/p/16899532.html