从观察者模式到spring事件机制
观察者模式(Observe Pattern)
定义对象之间的一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
业务开发中,观察者模式对我们很大的一个作用,在于实现业务的解耦。
spring事件机制
Spring 基于观察者模式,实现了自身的事件机制,由三部分组成:
-
事件 ApplicationEvent:通过继承它,实现自定义事件。另外,通过它的 source 属性可以获取事件源,timestamp 属性可以获得发生时间。 事件发布者 ApplicationEventPublisher:通过它,可以进行事件的发布。 事件监听器 ApplicationListener:通过实现它,进行指定类型的事件的监听。
JDK 也内置了事件机制的实现,考虑到通用性,Spring 的事件机制是基于它之上进行拓展。 因此, ApplicationEvent 继承自 java.util.EventObject ApplicationListener 继承自 java.util.EventListener。
依赖
<!-- 实现对 Spring MVC 的自动化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
1. 自定义事件
继承 ApplicationEvent 类
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; } }
2. 发布类
@Service public class UserService implements ApplicationEventPublisherAware { // <*> private Logger logger = LoggerFactory.getLogger(getClass()); private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } public void register(String username) { // ... 执行注册逻辑 logger.info("[register][执行用户({}) 的注册逻辑]", username); // <*> ... 发布 applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username)); } }
3. 监听类
第一种
@Service public class EmailService implements ApplicationListener<UserRegisterEvent> { // <*> private Logger logger = LoggerFactory.getLogger(getClass()); @Override @Async // <1> public void onApplicationEvent(UserRegisterEvent event) { // <*> logger.info("[onApplicationEvent][给用户({}) 发送邮件]", event.getUsername()); } }
【可以不加】<1> 处,设置 @Async 注解,声明异步执行。毕竟实际场景下,发送邮件可能比较慢,又是非关键逻辑。
第二种
@Service public class CouponService { private Logger logger = LoggerFactory.getLogger(getClass()); @EventListener // <1> public void addCoupon(UserRegisterEvent event) { logger.info("[addCoupon][给用户({}) 发放优惠劵]", event.getUsername()); } }
spring内置权限
配置监听顺序
上一篇:
IDEA上Java项目控制台中文乱码