事件

编写一个ApplicationListener

你可以继承一个抽象类,该抽象类会监听此类事件,并根据事件类型调用相应的方法。为此,请重写与相关事件对应的方法,如下所示:spring-doc.cadn.net.cn

public class BeforeSaveEventListener extends AbstractRepositoryEventListener {

  @Override
  public void onBeforeSave(Object entity) {
    ... logic to handle inspecting the entity before the Repository saves it
  }

  @Override
  public void onAfterDelete(Object entity) {
    ... send a message that this entity has been deleted
  }
}

然而,需要注意的是,这种方法不会根据实体的类型进行区分。你必须自己检查这一点。spring-doc.cadn.net.cn

编写注解处理器

另一种方法是使用带注解的处理器,该处理器根据领域类型对事件进行过滤。spring-doc.cadn.net.cn

要声明一个处理器,请创建一个 POJO,并在其上添加 @RepositoryEventHandler 注解。这会告知 BeanPostProcessor 该类需要被检查以查找处理器方法。spring-doc.cadn.net.cn

一旦 BeanPostProcessor 发现带有此注解的 Bean,它就会遍历该 Bean 中暴露的方法,并查找与相应事件对应的注解。例如,若要在带注解的 POJO 中处理不同类型领域对象的 BeforeSaveEvent 实例,您可以按如下方式定义您的类:spring-doc.cadn.net.cn

@RepositoryEventHandler (1)
public class PersonEventHandler {

  @HandleBeforeSave
  public void handlePersonSave(Person p) {
    // … you can now deal with Person in a type-safe way
  }

  @HandleBeforeSave
  public void handleProfileSave(Profile p) {
    // … you can now deal with Profile in a type-safe way
  }
}
1 可以通过使用(例如)@RepositoryEventHandler(Person.class) 来缩小此处理器所适用的类型范围。

您所关注的事件所属的领域类型,由注解方法的第一个参数的类型决定。spring-doc.cadn.net.cn

要注册您的事件处理器,可以使用 Spring 的某个 @Component 刻板注解(stereotype)标记该类(以便能被 @SpringBootApplication@ComponentScan 自动发现),或者在您的 ApplicationContext 中声明一个带注解的 bean 实例。随后,BeanPostProcessor 中创建的 RepositoryRestMvcConfiguration 会检查该 bean 中的处理器,并将其绑定到相应的事件上。以下示例展示了如何为 Person 类创建一个事件处理器:spring-doc.cadn.net.cn

@Configuration
public class RepositoryConfiguration {

  @Bean
  PersonEventHandler personEventHandler() {
    return new PersonEventHandler();
  }
}
Spring Data REST 事件是经过定制的Spring 应用程序事件。默认情况下,Spring 事件是同步的,除非它们跨越某个边界被重新发布(例如触发 WebSocket 事件或进入另一个线程)。