实体回调
Spring Data 基础结构提供了用于在调用某些方法之前和之后修改实体的钩子。
这些所谓的实例提供了一种方便的方法来检查和可能修改回调样式的实体。
An 看起来很像一个专门的 .
一些 Spring Data 模块发布允许修改给定实体的存储特定事件(例如 )。在某些情况下,例如在使用不可变类型时,这些事件可能会导致麻烦。
此外,事件发布依赖于 .如果使用 asynchronous 进行配置,则可能会导致不可预测的结果,因为事件处理可以分叉到 Thread 上。EntityCallback
EntityCallback
ApplicationListener
BeforeSaveEvent
ApplicationEventMulticaster
TaskExecutor
实体回调为集成点提供同步和反应式 API,以保证在处理链中定义明确的检查点按顺序执行,返回可能修改的实体或反应式包装器类型。
实体回调通常按 API 类型分隔。这种分离意味着同步 API 仅考虑同步实体回调,而反应式实现仅考虑反应式实体回调。
实体回调 API 已在 Spring Data Commons 2.2 中引入。这是应用实体修改的推荐方法。
在调用可能注册的实例之前,仍会发布特定于 store 的现有 store specific。 |
实现实体回调
An 通过其泛型类型参数直接与其域类型关联。
每个 Spring Data 模块通常附带一组涵盖实体生命周期的预定义接口。EntityCallback
EntityCallback
EntityCallback
@FunctionalInterface
public interface BeforeSaveCallback<T> extends EntityCallback<T> {
/**
* Entity callback method invoked before a domain object is saved.
* Can return either the same or a modified instance.
*
* @return the domain object to be persisted.
*/
(1)
T onBeforeSave(T entity, (2)
String collection); (3)
}
1 | BeforeSaveCallback 在保存实体之前调用的特定方法。返回可能修改的实例。 |
2 | 实体。 |
3 | 许多特定于 store 的参数,例如实体持久化到的集合。 |
EntityCallback
@FunctionalInterface
public interface ReactiveBeforeSaveCallback<T> extends EntityCallback<T> {
/**
* Entity callback method invoked on subscription, before a domain object is saved.
* The returned Publisher can emit either the same or a modified instance.
*
* @return Publisher emitting the domain object to be persisted.
*/
(1)
Publisher<T> onBeforeSave(T entity, (2)
String collection); (3)
}
1 | BeforeSaveCallback 在保存实体之前在 Subscription 上调用的特定方法。发出可能修改的实例。 |
2 | 实体。 |
3 | 许多特定于 store 的参数,例如实体持久化到的集合。 |
可选的实体回调参数由实现的 Spring Data 模块定义,并从 的调用站点推断。EntityCallback.callback() |
实现适合您应用程序需求的接口,如以下示例所示:
BeforeSaveCallback
class DefaultingEntityCallback implements BeforeSaveCallback<Person>, Ordered { (2)
@Override
public Object onBeforeSave(Person entity, String collection) { (1)
if(collection == "user") {
return // ...
}
return // ...
}
@Override
public int getOrder() {
return 100; (2)
}
}
1 | 根据您的需求实现 callback。 |
2 | 如果存在同一域类型的多个实体回调,则可能会对实体回调进行排序。排序遵循最低优先级。 |
注册实体回调
EntityCallback
如果 bean 在 .
大多数模板 API 已经实现了,因此可以访问ApplicationContext
ApplicationContextAware
ApplicationContext
以下示例说明了有效实体回调注册的集合:
EntityCallback
@Order(1) (1)
@Component
class First implements BeforeSaveCallback<Person> {
@Override
public Person onBeforeSave(Person person) {
return // ...
}
}
@Component
class DefaultingEntityCallback implements BeforeSaveCallback<Person>,
Ordered { (2)
@Override
public Object onBeforeSave(Person entity, String collection) {
// ...
}
@Override
public int getOrder() {
return 100; (2)
}
}
@Configuration
public class EntityCallbackConfiguration {
@Bean
BeforeSaveCallback<Person> unorderedLambdaReceiverCallback() { (3)
return (BeforeSaveCallback<Person>) it -> // ...
}
}
@Component
class UserCallbacks implements BeforeConvertCallback<User>,
BeforeSaveCallback<User> { (4)
@Override
public Person onBeforeConvert(User user) {
return // ...
}
@Override
public Person onBeforeSave(User user) {
return // ...
}
}
1 | BeforeSaveCallback 从 Annotation 接收其 order。@Order |
2 | BeforeSaveCallback 通过 interface 实现接收其 order。Ordered |
3 | BeforeSaveCallback 使用 Lambda 表达式。默认情况下未排序,最后调用。请注意,由 lambda 表达式实现的回调不会公开键入信息,因此使用不可分配的实体调用这些回调会影响回调吞吐量。使用 or 为回调 Bean 启用类型过滤。class enum |
4 | 将多个实体回调接口合并到一个实现类中。 |