| 
         对于最新的稳定版本,请使用 Spring Data Relational 3.4.0!  | 
    
实体回调
Spring Data 基础结构提供了用于在调用某些方法之前和之后修改实体的钩子。
那些所谓的EntityCallback实例提供了一种方便的方法来检查和可能修改回调样式中的实体。
 一EntityCallback看起来非常像一个专门的ApplicationListener.
某些 Spring Data 模块发布特定于存储的事件(例如BeforeSaveEvent),允许修改给定实体。在某些情况下,例如在使用不可变类型时,这些事件可能会导致麻烦。
此外,事件发布依赖于ApplicationEventMulticaster.如果使用异步TaskExecutor这可能会导致不可预测的结果,因为事件处理可能会分叉到 Thread 上。
实体回调为集成点提供同步和反应式 API,以保证在处理链中定义明确的检查点按顺序执行,返回可能修改的实体或反应式包装器类型。
实体回调通常按 API 类型分隔。这种分离意味着同步 API 仅考虑同步实体回调,而反应式实现仅考虑反应式实体回调。
| 
 实体回调 API 已在 Spring Data Commons 2.2 中引入。这是应用实体修改的推荐方法。
现有商店特定  | 
实现实体回调
一EntityCallback通过其泛型类型参数直接与其域类型关联。
每个 Spring Data 模块通常附带一组预定义的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(). | 
实现适合您应用程序需求的接口,如以下示例所示:
BeforeSaveCallbackclass 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 | 如果存在同一域类型的多个实体回调,则可能会对实体回调进行排序。排序遵循最低优先级。 | 
注册实体回调
EntityCallbackbean 由 store 特定的实现拾取,以防它们在ApplicationContext.
大多数模板 API 已经实现了ApplicationContextAware因此可以访问ApplicationContext
以下示例说明了有效实体回调注册的集合:
EntityCallbackBean 注册@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从@Order注解。 | 
| 2 | BeforeSaveCallback通过Orderedinterface 实现。 | 
| 3 | BeforeSaveCallback使用 Lambda 表达式。默认情况下未排序,最后调用。请注意,由 lambda 表达式实现的回调不会公开键入信息,因此使用不可分配的实体调用这些回调会影响回调吞吐量。使用class或enum为回调 Bean 启用类型过滤。 | 
| 4 | 将多个实体回调接口合并到一个实现类中。 |