Events

在与实体配合工作的过程中,REST 导出器会发出八种不同的事件:

The REST exporter emits eight different events throughout the process of working with an entity:

  • BeforeCreateEvent

  • AfterCreateEvent

  • BeforeSaveEvent

  • AfterSaveEvent

  • BeforeLinkSaveEvent

  • AfterLinkSaveEvent

  • BeforeDeleteEvent

  • AfterDeleteEvent

Writing an ApplicationListener

您可以对一个监听这几种事件并调用基于事件类型适当方法的抽象类进行子类化。要这样做,请覆盖有问题的事件的方法,如下所示:

You can subclass an abstract class that listens for these kinds of events and calls the appropriate method based on the event type. To do so, override the methods for the events in question, as follows:

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

但是,需要注意的一点是,这种方法并未根据实体类型进行区分。您必须自己进行检查。

One thing to note with this approach, however, is that it makes no distinction based on the type of the entity. You have to inspect that yourself.

Writing an Annotated Handler

另一种方法是使用带注释的处理程序,该处理程序根据域类型来筛选事件。

Another approach is to use an annotated handler, which filters events based on domain type.

要声明一个处理程序,请创建一个 POJO 并对其放置 @RepositoryEventHandler 注释。这会告诉 BeanPostProcessor 此类需要进行处理程序方法检查。

To declare a handler, create a POJO and put the @RepositoryEventHandler annotation on it. This tells the BeanPostProcessor that this class needs to be inspected for handler methods.

一旦 BeanPostProcessor 找到带此注释的 bean,它就会遍历公开方法并查找与所讨论事件相对应的注释。例如,若要在面向不同域类型的注释 POJO 中处理 BeforeSaveEvent 实例,可以如下定义类:

Once the BeanPostProcessor finds a bean with this annotation, it iterates over the exposed methods and looks for annotations that correspond to the event in question. For example, to handle BeforeSaveEvent instances in an annotated POJO for different kinds of domain types, you could define your class as follows:

@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 It’s possible to narrow the types to which this handler applies by using (for example) @RepositoryEventHandler(Person.class).

您感兴趣的事件的域类型由注释方法第一个参数的类型确定。

The domain type whose events you are interested in is determined from the type of the first parameter of the annotated methods.

要注册您的事件处理程序,请用 Spring @Component 规则之一标记此类(以便 @SpringBootApplication@ComponentScan 可以选取它),或在 ApplicationContext 中声明注释 bean 的实例。然后,在 RepositoryRestMvcConfiguration 中创建的 BeanPostProcessor 会检查该 bean 的处理程序并将其连接到正确的事件。以下示例显示如何为 Person 类创建事件处理程序:

To register your event handler, either mark the class with one of Spring’s @Component stereotypes (so that it can be picked up by @SpringBootApplication or @ComponentScan) or declare an instance of your annotated bean in your ApplicationContext. Then the BeanPostProcessor that is created in RepositoryRestMvcConfiguration inspects the bean for handlers and wires them to the correct events. The following example shows how to create an event handler for the Person class:

@Configuration
public class RepositoryConfiguration {

  @Bean
  PersonEventHandler personEventHandler() {
    return new PersonEventHandler();
  }
}

Spring Data REST 事件是自定义“ Spring application events”的。默认情况下,Spring 事件是同步的,除非它们跨界重新发布(例如发出 WebSocket 事件或交叉进入一个线程)。

Spring Data REST events are customized Spring application events. By default, Spring events are synchronous, unless they get republished across a boundary (such as issuing a WebSocket event or crossing into a thread).