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
相关推荐
小灰灰__17 分钟前
IDEA加载通义灵码插件及使用指南
java·ide·intellij-idea
夜雨翦春韭21 分钟前
Java中的动态代理
java·开发语言·aop·动态代理
Elastic 中国社区官方博客36 分钟前
如何将数据从 AWS S3 导入到 Elastic Cloud - 第 3 部分:Elastic S3 连接器
大数据·elasticsearch·搜索引擎·云计算·全文检索·可用性测试·aws
程序媛小果41 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
掘金-我是哪吒1 小时前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
追风林1 小时前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
芒果披萨1 小时前
El表达式和JSTL
java·el
duration~2 小时前
Maven随笔
java·maven
zmgst2 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD2 小时前
前后端分离,Jackson,Long精度丢失
java