生命周期事件

Cassandra 映射框架具有多个内置事件,您的应用程序可以通过在 . 基于 Spring 的应用程序上下文事件基础结构使其他产品(例如 Spring Integration)可以轻松接收这些事件,因为它们是基于 Spring 的应用程序中众所周知的事件机制。org.springframework.context.ApplicationEventApplicationContextspring-doc.cn

要在对象进入数据库之前拦截对象,可以注册一个覆盖该方法的 AbstractCassandraEventListener 子类。 调度事件时,将调用侦听器并传递域对象(Java 实体)。 实体生命周期事件的成本可能很高,并且在加载大型结果集时,您可能会注意到性能配置文件发生了变化。 您可以在 Template API 上禁用生命周期事件。 以下示例使用该方法:onBeforeSave(…)onBeforeSavespring-doc.cn

class BeforeSaveListener extends AbstractCassandraEventListener<Person> {
	@Override
	public void onBeforeSave(BeforeSaveEvent<Person> event) {
		// … change values, delete them, whatever …
	}
}

在 Spring 中声明这些 bean 将导致在调度事件时调用它们。ApplicationContextspring-doc.cn

  • onBeforeSave:在数据库中插入或更新行之前,但在创建 .CassandraTemplate.insert(…).update(…)Statementspring-doc.cn

  • onAfterSave:在数据库中插入或更新行后的调用和操作。CassandraTemplate…insert(…).update(…)spring-doc.cn

  • onBeforeDelete:在从数据库中删除行之前调用的操作。CassandraTemplate.delete(…)spring-doc.cn

  • onAfterDelete:从数据库中删除行后调用的操作。CassandraTemplate.delete(…)spring-doc.cn

  • onAfterLoad:从数据库中检索每一行后,在 、 和 方法中调用。CassandraTemplate.select(…).slice(…).stream(…)spring-doc.cn

  • onAfterConvert:将从数据库中检索到的行转换为 POJO 后,在 、 和 方法中调用。CassandraTemplate.select(…).slice(…).stream(…)spring-doc.cn

生命周期事件仅针对根级类型发出。 在聚合根中用作属性的复杂类型不受事件发布的约束。

实体回调

Spring Data 基础结构提供了用于在调用某些方法之前和之后修改实体的钩子。 这些所谓的实例提供了一种方便的方法来检查和可能修改回调样式的实体。
An 看起来很像一个专门的 . 一些 Spring Data 模块发布允许修改给定实体的存储特定事件(例如 )。在某些情况下,例如在使用不可变类型时,这些事件可能会导致麻烦。 此外,事件发布依赖于 .如果使用 asynchronous 进行配置,则可能会导致不可预测的结果,因为事件处理可以分叉到 Thread 上。
EntityCallbackEntityCallbackApplicationListenerBeforeSaveEventApplicationEventMulticasterTaskExecutorspring-doc.cn

实体回调为集成点提供同步和反应式 API,以保证在处理链中定义明确的检查点按顺序执行,返回可能修改的实体或反应式包装器类型。spring-doc.cn

实体回调通常按 API 类型分隔。这种分离意味着同步 API 仅考虑同步实体回调,而反应式实现仅考虑反应式实体回调。spring-doc.cn

实体回调 API 已在 Spring Data Commons 2.2 中引入。这是应用实体修改的推荐方法。 在调用可能注册的实例之前,仍会发布特定于 store 的现有 store specific。ApplicationEventsEntityCallbackspring-doc.cn

实现实体回调

An 通过其泛型类型参数直接与其域类型关联。 每个 Spring Data 模块通常附带一组涵盖实体生命周期的预定义接口。EntityCallbackEntityCallbackspring-doc.cn

剖析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()

实现适合您应用程序需求的接口,如以下示例所示:spring-doc.cn

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 已经实现了,因此可以访问ApplicationContextApplicationContextAwareApplicationContextspring-doc.cn

以下示例说明了有效实体回调注册的集合:spring-doc.cn

Bean 注册示例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 启用类型过滤。classenum
4 将多个实体回调接口合并到一个实现类中。

特定于 Store 的 EntityCallbacks

Spring Data for Apache Cassandra 使用 API 来支持其审计,并对以下回调做出反应。EntityCallbackspring-doc.cn

表 1.支持的实体回调
回调 方法 描述 次序

ReactiveBeforeConvertCallback BeforeConvertCallbackspring-doc.cn

onBeforeConvert(T entity, CqlIdentifier tableName)spring-doc.cn

在将域对象转换为 . 域对象可以更新以包括 .StatementStatementspring-doc.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cn

ReactiveAuditingEntityCallback AuditingEntityCallbackspring-doc.cn

onBeforeConvert(Object entity, CqlIdentifier tableName)spring-doc.cn

标记已创建或修改的可审计实体spring-doc.cn

100spring-doc.cn

ReactiveBeforeSaveCallback BeforeSaveCallbackspring-doc.cn

onBeforeSave(T entity, CqlIdentifier tableName, Statement statement)spring-doc.cn

在保存域对象之前调用。
可以在创建后修改目标对象。提供的语句包含所有映射的实体信息,但对域对象的更改不包含在 .
StatementStatementspring-doc.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cn