Springboot 优雅实现观察者模式

解耦神器之观察者模式
SpringBoot 自带的观察者模式

观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,其主要解决一个对象状态改变给其他关联对象通知的问题,保证易用和低耦合。一个典型的应用场景是:当用户注册以后,需要给用户发送邮件,发送优惠券等操作,如下图所示。
在这里插入图片描述

使用观察者模式后:
在这里插入图片描述

UserService 在完成自身的用户注册逻辑之后,仅仅只需要发布一个 UserRegisterEvent 事件,而无需关注其它拓展逻辑。其它 Service 可以自己订阅 UserRegisterEvent 事件,实现自定义的拓展逻辑。Spring的事件机制主要由3个部分组成。

ApplicationEvent:通过继承它,实现自定义事件。另外,通过它的 source 属性可以获取事件源,timestamp 属性可以获得发生时间。
ApplicationEventPublisher:通过实现它,来发布变更事件。
ApplicationEventListener:通过实现它,来监听指定类型事件并响应动作。这里就以上面的用户注册为例,来看看代码示例。首先定义用户注册事件 UserRegisterEvent。

publicclass 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;
    }
}

然后定义用户注册服务类,实现 ApplicationEventPublisherAware 接口,从而将 ApplicationEventPublisher 注入进来。从下面代码可以看到,在执行完注册逻辑后,调用了 ApplicationEventPublisher的 publishEvent(ApplicationEvent event) 方法,发布了 UserRegisterEvent 事件。

@Service
publicclass UserService implements ApplicationEventPublisherAware { // <1>
    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);
        // <2> ... 发布
        applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));
    }
}

<1> 处,实现 ApplicationEventPublisherAware 接口,从而将 ApplicationEventPublisher 注入到其中。
<2> 处,在执行完注册逻辑后,调用 ApplicationEventPublisher 的 #publishEvent(ApplicationEvent event) 方法,发布「3.2 UserRegisterEvent」事件。

创建邮箱Service,实现 ApplicationListener 接口,通过 E 泛型设置感兴趣的事件,实现 onApplicationEvent(E event) 方法,针对监听的 UserRegisterEvent 事件,进行自定义处理。

@Service
public class EmailService implements ApplicationListener<UserRegisterEvent> { // <1>

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    @Async // <3>
    public void onApplicationEvent(UserRegisterEvent event) { // <2>
        logger.info("[onApplicationEvent][给用户({}) 发送邮件]", event.getUsername());
    }

}

<1> 处,实现 ApplicationListener 接口,通过 E 泛型设置感兴趣的事件。
<2> 处,实现 #onApplicationEvent(E event) 方法,针对监听的 UserRegisterEvent 事件,进行自定义处理。
【可以不加】<3> 处,锦上添花,设置 @Async 注解,声明异步执行。毕竟实际场景下,发送邮件可能比较慢,又是非关键逻辑。

创建优惠券Service,不同于上面的实现 ApplicationListener 接口方式,在方法上,添加 @EventListener 注解,并设置监听的事件为 UserRegisterEvent。这是另一种使用方式。

@Service
publicclass CouponService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @EventListener// <1>
    public void addCoupon(UserRegisterEvent event) {
        logger.info("[addCoupon][给用户({}) 发放优惠劵]", event.getUsername());
    }
}

<1> 处,在方法上,添加 @EventListener 注解,并设置监听的事件为 UserRegisterEvent。这是另一种使用方式!

看到这里,细心的同学可能想到了发布订阅模式,其实观察者模式于发布订阅还是有区别的,简单来说,发布订阅模式属于广义上的观察者模式,在观察者模式的 Subject 和 Observer 的基础上,引入 Event Channel 这个中介,进一步解耦。图示如下,可以看出,观察者模式更加轻量,通常用于单机,而发布订阅模式相对而言更重一些,通常用于分布式环境下的消息通知场景。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,可以使用Java中内置的观察者模式实现事件驱动的编程。具体步骤如下: 1. 定义观察者接口:通常情况下,观察者接口包含一个update()方法,用于接收事件通知。 ```java public interface Observer { void update(); } ``` 2. 定义事件类:通常情况下,事件类包含事件类型和事件数据。 ```java public class Event { private EventType eventType; private Object eventData; // getters and setters } ``` 3. 定义事件类型枚举类:用于区分不同的事件类型。 ```java public enum EventType { EVENT_TYPE_1, EVENT_TYPE_2 // ... } ``` 4. 定义观察者实现类:实现Observer接口,并在update()方法中处理事件。 ```java public class MyObserver implements Observer { @Override public void update() { // 处理事件 } } ``` 5. 定义事件发布类:用于发布事件。 ```java @Component public class EventPublisher { @Autowired private List<Observer> observers; public void publish(Event event) { for (Observer observer : observers) { observer.update(event); } } } ``` 6. 在需要监听事件的地方注册观察者:使用@Autowired注入EventPublisher,并调用其publish()方法发布事件。 ```java @Component public class MyService implements Observer { @Autowired private EventPublisher eventPublisher; @PostConstruct public void init() { eventPublisher.register(this); } @Override public void update(Event event) { // 处理事件 } } ``` 以上就是使用Spring Boot提供的观察者模式的基本步骤。需要注意的是,观察者模式适用于一对多的场景,即一个事件可以被多个观察者接收和处理。在实际应用中,也可以根据具体的业务需求进行扩展和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值