Spring Data访问Elasticsearch----实体回调Entity Callbacks

Spring Data访问Elasticsearch----实体回调Entity Callbacks

Spring Data基础结构提供了钩子,用于在调用某些方法之前和之后修改实体。这些所谓的EntityCallback实例提供了一种方便的方式来检查并可能以回调风格修改实体。
EntityCallback看起来很像一个专门的ApplicationListener。一些Spring Data模块发布特定于存储的事件(如BeforeSaveEvent),允许修改给定的实体。在某些情况下,例如在处理不可变类型时,这些事件可能会造成麻烦。此外,事件发布依赖于ApplicationEventMulticaster。如果使用异步TaskExecutor进行配置,可能会导致不可预测的结果,因为事件处理可能会分叉到线程上。
实体回调为同步API和反应式(reactive)API提供了集成点,以保证在处理链中定义良好的检查点(checkpoints)按顺序执行,从而返回可能修改的实体或反应式包装器类型。
实体回调通常由API类型分隔。这种分离意味着同步API只考虑同步实体回调,而反应式实现只考虑反应式实体回调。
实体回调API是在Spring Data Commons 2.2中引入的。这是应用实体修改的推荐方式。在调用可能注册的EntityCallback实例之前,仍会发布现有的特定于存储的ApplicationEvents。

一、实现实体回调

EntityCallback通过其泛型类型参数与其域类型直接关联。每个Spring Data模块通常附带一组覆盖实体生命周期的预定义EntityCallback接口。
EntityCallback的剖析

java 复制代码
@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. 许多存储特定的参数,如实体持久化到的集合。

反应式的EntityCallback剖析

java 复制代码
@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. 在保存实体之前,在subscription上调用BeforeSaveCallback特定的方法。发出一个可能已修改的实例。
2. 就在持久化之前的实体。
3. 许多特定于存储的参数,如实体持久化到的集合。

可选的实体回调参数由实现的Spring Data模块定义,并从EntityCallback.callback()的调用位置推断。

实现适合您的应用程序需求的接口,如下面的示例所示:
示例BeforeSaveCallback

java 复制代码
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. 根据你的要求实施回调。
2. 如果同一域类型存在多个实体回调,则可能会对实体回调进行排序。排序遵循最低优先级。

二、注册实体回调

如果EntityCallback beans在ApplicationContext中注册,则由特定于存储的实现拾取。大多数template API已经实现ApplicationContextAware,因此可以访问ApplicationContext

以下示例解释了有效实体回调注册的集合:
EntityCallback Bean注册示例

java 复制代码
@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通过Ordered接口实现接收其顺序。
3. BeforeSaveCallback使用lambda表达式。默认情况下未排序,最后调用。请注意,由lambda表达式实现的回调不会公开类型信息,因此使用不可分配的实体调用这些信息会影响回调吞吐量。使用类或枚举为回调bean启用类型筛选。
4. 在一个实现类中组合多个实体回调接口。

三、存储特定的EntityCallbacks

Spring Data Elasticsearch在内部使用EntityCallback API来支持其auditing,并对以下回调做出反应:
表1:支持的实体回调

Callback Method Description Order
Reactive/BeforeConvertCallback onBeforeConvert(T entity, IndexCoordinates index) 在域对象转换为org.springframework.data.elasticsearch.core.document.Document之前调用。可以返回实体或修改后的实体,然后将其转换。 Ordered.LOWEST_PRECEDENCE
Reactive/AfterLoadCallback onAfterLoad(Document document, Class type, IndexCoordinates indexCoordinates) 在从Elasticsearch得到的结果被读入org.springframework.data.elasticsearch.core.document.Document之后调用。 Ordered.LOWEST_PRECEDENCE
Reactive/AfterConvertCallback onAfterConvert(T entity, Document document, IndexCoordinates indexCoordinates) 在从Elasticsearch读取结果数据时,从"org.springframework.data.aelasticsearch.core.document.document"转换为域对象后调用。 Ordered.LOWEST_PRECEDENCE
Reactive/AuditingEntityCallback onBeforeConvert(Object entity, IndexCoordinates index) 标记创建或修改的可审核实体 100
Reactive/AfterSaveCallback T onAfterSave(T entity, IndexCoordinates index) 在保存域对象后调用。 Ordered.LOWEST_PRECEDENCE
相关推荐
吾日三省吾码2 小时前
JVM 性能调优
java
弗拉唐3 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi773 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
少说多做3433 小时前
Android 不同情况下使用 runOnUiThread
android·java
知兀3 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
蓝黑20204 小时前
IntelliJ IDEA常用快捷键
java·ide·intellij-idea
Ysjt | 深4 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
shuangrenlong4 小时前
slice介绍slice查看器
java·ubuntu
牧竹子4 小时前
对原jar包解压后修改原class文件后重新打包为jar
java·jar