生命周期事件

Spring Data JDBC 将生命周期事件发布到 ApplicationListener 对象,通常是应用程序上下文中的 Bean。事件是对特定生命周期阶段的通知。与实体回调相反,事件旨在用于通知。事务监听器将在事务完成后接收事件。事件和回调仅对聚合根触发。如果要处理非根实体,则需要通过包含聚合根的监听器来处理。

实体生命周期事件可能代价高昂,并且在加载大型结果集时可能会注意到性能配置文件的变化。您可以在 模板 API 上禁用生命周期事件。

例如,以下监听器在聚合保存之前被调用

@Bean
ApplicationListener<BeforeSaveEvent<Object>> loggingSaves() {

	return event -> {

		Object entity = event.getEntity();
		LOG.info("{} is getting saved.", entity);
	};
}

如果只想处理特定域类型的事件,可以从 AbstractRelationalEventListener 派生您的监听器,并覆盖一个或多个 onXXX 方法,其中 XXX 代表事件类型。回调方法只会对与域类型及其子类型相关的事件调用,因此不需要进一步转换。

class PersonLoadListener extends AbstractRelationalEventListener<Person> {

	@Override
	protected void onAfterLoad(AfterLoadEvent<Person> personLoad) {
		LOG.info(personLoad.getEntity());
	}
}

下表描述了可用的事件。有关处理步骤之间确切关系的更多详细信息,请参阅 可用回调的描述,它们与事件一一对应。

表 1. 可用事件
事件 何时发布

BeforeDeleteEvent

在聚合根被删除之前。

AfterDeleteEvent

在聚合根被删除之后。

BeforeConvertEvent

在聚合根被转换为执行 SQL 语句的计划之前,但在决定聚合是新还是旧之后,即是否需要更新或插入。

BeforeSaveEvent

在聚合根被保存(即插入或更新)之前(但在决定是否插入或更新之后)。

AfterSaveEvent

在聚合根被保存(即插入或更新)之后。

AfterConvertEvent

在聚合根从数据库 ResultSet 创建并设置其所有属性之后。

生命周期事件依赖于 ApplicationEventMulticaster,在 SimpleApplicationEventMulticaster 的情况下,可以使用 TaskExecutor 配置它,因此不保证何时处理事件。

特定于存储的 EntityCallbacks

Spring Data JDBC 使用 EntityCallback API 来支持其审计功能,并对下表中列出的回调做出反应。

表 2. Spring Data JDBC 执行的不同过程的处理步骤和回调。
过程 EntityCallback / 处理步骤 注释

删除

BeforeDeleteCallback

在实际删除之前。

聚合根和该聚合的所有实体都将从数据库中删除。

AfterDeleteCallback

在聚合被删除之后。

保存

确定是否要执行聚合的插入或更新,具体取决于它是否为新聚合。

BeforeConvertCallback

如果要以编程方式设置 ID,则这是正确的回调。在上一步中,新聚合被检测为新聚合,并且此步骤中生成的 ID 将在下一步中使用。

将聚合转换为聚合更改,它是要针对数据库执行的一系列 SQL 语句。在此步骤中,将决定是聚合提供 ID 还是 ID 仍然为空并期望由数据库生成。

BeforeSaveCallback

对聚合根所做的更改可能会被考虑,但 ID 值是否将发送到数据库的决定已在上一步中做出。不要使用此方法为新聚合创建 ID。请改用 BeforeConvertCallback

上面确定的 SQL 语句将针对数据库执行。

AfterSaveCallback

在聚合根被保存(即插入或更新)之后。

加载

使用一个或多个 SQL 查询加载聚合。从结果集中构造聚合。

AfterConvertCallback

我们鼓励使用回调而不是事件,因为它们支持使用不可变类,因此比事件更强大且用途更广。