Spring标准事件和自定义事件-观察者模式

  • spring事件
  • 系统事件
  • 自定义事件
  • 声明事件
  • 发布事件
  • 监听事件
  • 实现`ApplicationListener`接口
  • `@EventListener`注解。
  • 异步消息监听 :
  • 顺序监听 :
  • 通用消息
  • 声明通用消息事件
  • 监听通用消息事件



spring事件

在spring官方文档中说,本质上spring事件是一个标准的观察者模式。

spring 事件在Spring 4.2时做了重构。

系统事件

系统事件

描述

ContextRefreshedEvent

当应用容器(ApplicationContext)初始化或者刷新时发布的事件。例如 :ConfigurableApplicationContext的refresh()方法被调用时就会发布该事件。

ContextStartedEvent

通过调用ConfigurableApplicationContextstart()方法启动应用容器时发布的事件

ContextStoppedEvent

在调用ConfigurableApplicationContext接口的stop()方法时被发布的事件。

ContextClosedEvent

在调用ConfigurableApplicationContext接口的close()方法时被发布的事件。

RequestHandledEvent

Http请求完成后发送的消息事件。该事件进在Spring的DispatcherServlet中生效

ServletRequestHandledEvent

RequestHandledEvent 的子类,用于特定的Servlet上下文信息。

自定义事件

声明事件

添加好友事件为例 :

public class AddFriendEvent extends ApplicationEvent {
    private String userId;
    private String friendId;
    private String terminal;
    public AddFriendEvent(Object source,String userId,String friendId,String terminal) {
        super(source);
        this.userId = userId;
        this.friendId = friendId;
        this.terminal = terminal;
    }
}

发布事件

使用ApplicationEventPublisherpublishEvent()方法发布事件,在官方文档的示例中是让发布事件的对象实现 ApplicationEventPublisherAware 接口,在其中便能直接使用ApplicationEventPublisher 对象发送事件,但是感觉用起来过于复杂,两种方式如下 :

@Autowired
    private ApplicationEventPublisher publisher;

spring官方示例 :

public class EmailService implements ApplicationEventPublisherAware {
  private List<String> blockedList;
  private ApplicationEventPublisher publisher;
  
  public void setBlockedList(List<String> blockedList) {
  		this.blockedList = blockedList;
  }
  public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
  		this.publisher = publisher;
  }
  public void sendEmail(String address, String content) {
  		if (blockedList.contains(address)) {
  			publisher.publishEvent(new BlockedListEvent(this, address, content));
  			return;
  		}
  }
}

在spring 配置bean时,spring容器会自动的扫码实现了ApplicationEventPublisherAware接口的bean,并且自动的调用setApplicationEventPublisher()方法完成ApplicationEventPublisher 的set注入。

监听事件

spring 提供了多种实现事件监听的方式,在spring5.x主要方式实现ApplicationListener接口和使用@EventListener注解。

实现ApplicationListener接口

接收Spring事件需要创建一个对象实现ApplicationListener接口并且注册成Spring bean,代码实例如下 :

public class BlockedListNotifier implements ApplicationListener<BlockedListEvent> {
  private String notificationAddress;
  public void setNotificationAddress(String notificationAddress) {
  		this.notificationAddress = notificationAddress;
  }
  public void onApplicationEvent(BlockedListEvent event) {
  		// notify appropriate parties via notificationAddress...
  }
}

创建事件监听器需要实现泛型化(自定义的Spring事件)的ApplicationListener接口。当事件被发出后,onApplicationEvent()方法会被调用,事件处理逻辑可以写在该方法里。

@EventListener注解。

使用注解监听消息

public class BlockedListNotifier {
  private String notificationAddress;
  public void setNotificationAddress(String notificationAddress) {
  		this.notificationAddress = notificationAddress;
  }
  @EventListener
  public void processBlockedListEvent(BlockedListEvent event) {
  		// notify appropriate parties via notificationAddress...
  }
}
异步消息监听 :

使用 @Async 可以实现异步消息监听

@EventListener
@Async
public void processBlockedListEvent(BlockedListEvent event) {
  // BlockedListEvent is processed in a separate thread
}
顺序监听 :

使用 @Order(42) 可以实现顺序消息监听

@EventListener
@Order(42)
public void processBlockedListEvent(BlockedListEvent event) {
  // notify appropriate parties via notificationAddress...
}

通用消息

声明通用消息事件

public class EntityCreatedEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
  public EntityCreatedEvent(T entity) {
  	super(entity);
  }
  @Override
  public ResolvableType getResolvableType() {
  	return ResolvableType.forClassWithGenerics(getClass(),
	ResolvableType.forInstance(getSource()));
  }
}

监听通用消息事件

@EventListener
public void onPersonCreated(EntityCreatedEvent<Person> event) {
  // ...
}