Spring框架中设计模式之 观察者模式

观察者模式:Spring 事件机制基于观察者模式,可以让不同的组件之间解耦合,实现了松耦合。

@Component
public class MyEventPublisher {
  @Autowired
  private ApplicationEventPublisher eventPublisher;

  public void publishEvent() {
    MyEvent event = new MyEvent(this);
    eventPublisher.publishEvent(event);
  }
}

@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
  @Override
  public void onApplicationEvent(MyEvent event) {
    // do something
  }
}

public class MyEvent extends ApplicationEvent {
  public MyEvent(Object source) {
    super(source);
  }
}

在上述代码中,MyEventPublisher 发布了一个 MyEvent 事件,MyEventListener 监听 MyEvent 事件,当 MyEvent 事件被触发时,MyEventListener 的 onApplicationEvent 方法将被调用。

在 Spring 中,观察者模式主要应用在事件机制中。Spring 的事件机制是基于观察者模式实现的,其中事件源(Publisher)和事件监听器(Listener)分别对应着观察者模式中的 Subject 和 Observer。当事件源发生事件时,会通知所有的事件监听器,并触发相应的事件处理方法。

我们再来看一个使用观察者模式的示例代码:

@Component
public class UserService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void register(User user) {
        // 注册用户
        ...
        // 发送注册成功事件
        eventPublisher.publishEvent(new UserRegisteredEvent(user));
    }
}

@Component
public class UserRegisteredEventListener implements ApplicationListener<UserRegisteredEvent> {
    @Override
    public void onApplicationEvent(UserRegisteredEvent event) {
        // 处理注册成功事件
        ...
    }
}

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    UserService userService = context.getBean(UserService.class);
    User user = new User("Alice", "123456");
    userService.register(user);
}

在上面的代码中,UserService 发布了一个 UserRegisteredEvent 事件,并由 UserRegisteredEventListener 来处理该事件。在 main 方法中,我们从容器中获取了 UserService 实例,并调用了 register 方法来触发事件的发布。当事件被发布时,Spring 会自动调用所有注册了 UserRegisteredEvent 事件监听器的 onApplicationEvent 方法来处理事件。

在 Spring 中,事件机制是通过 ApplicationEventPublisher 接口和 ApplicationListener 接口实现的。当事件源发布事件时,会调用 ApplicationEventPublisher 接口的 publishEvent 方法来通知所有的事件监听器。而事件监听器需要实现 ApplicationListener 接口,并指定要监听的事件类型。当事件发生时,Spring 会自动调用相应事件监听器的 onApplicationEvent 方法来处理事件。

在实现上,Spring 使用了 ConcurrentMap 来存储事件监听器。当一个新的事件监听器被注册时,Spring 会将其添加到相应的事件类型的监听器列表中。而当事件源发布事件时,Spring 会根据事件类型来查找相应的事件监听器,并调用其 onApplicationEvent 方法来处理事件。由于 ConcurrentMap 的线程安全性,Spring 的事件机制是线程安全的,可以在多线程环境下使用。