Lifecycle Events

Spring Data JDBC 将生命周期事件发布到 ApplicationListener 对象,通常是应用程序上下文中的 Bean。事件是关于特定生命周期阶段的通知。与实体回调相对,事件旨在用于通知。事务监听器将在事务完成后接收事件。事件和回调仅对聚合根触发。如果你想处理非根实体,你需要通过监听器为包含聚合根执行此操作。 实体生命周期事件可能代价高昂,并且在加载大型结果集时,您可能会注意到性能曲线发生变化。您可以在 Template 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());
	}
}

下表介绍了可用事件。有关过程步骤之间确切关系的更多详细信息,请参见映射到事件的一对一 description of available callbacks

Table 1. Available events
Event When It Is Published

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.html[BeforeDeleteEvent]

在聚合根被删除之前。

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.html[AfterDeleteEvent]

在聚合根被删除之后。

{spring-data-jdbc-javadoc}/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.html[BeforeConvertEvent]

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

{spring-data-jdbc-javadoc}/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.html[BeforeSaveEvent]

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

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/AfterSaveEvent.html[AfterSaveEvent]

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

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/AfterConvertEvent.html[AfterConvertEvent]

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

生命周期事件依赖 ApplicationEventMulticaster,在使用 SimpleApplicationEventMulticaster 的情况下,它可以通过 TaskExecutor 进行配置,因此无法保证事件的处理时间。

Store-specific EntityCallbacks

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

Table 2. Process Steps and Callbacks of the Different Processes performed by Spring Data JDBC.
Process EntityCallback / Process Step Comment

Delete

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.html[BeforeDeleteCallback]

Before the actual deletion.

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

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/AfterDeleteCallback.html[AfterDeleteCallback]

在聚合被删除之后。

Save

确定是否根据聚合的是否为新的执行聚合的插入或更新。

{spring-data-jdbc-javadoc}/org/springframework/data/relational/core/mapping/event/BeforeConvertCallback.html[BeforeConvertCallback]

如果您希望以编程方式设置 id,则这是正确的回调。在上一步中,新聚合被检测到,并且在此步骤中生成的 Id 将用于后续步骤。

将聚合转换为聚合更改,这会成为一系列需要对数据库执行的 SQL 语句。在此步骤中,系统会确定是通过聚合提供了 ID,还是 ID 仍然为空且预期由数据库生成。

{spring-data-jdbc-javadoc}/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.html[BeforeSaveCallback]

可考虑对聚合根进行的更改,但关于是否将 id 值发送到数据库的决策已在上一步中做出。不要将其用于创建新聚合的 Id。请改为使用 BeforeConvertCallback

上面确定的 SQL 语句将在数据库中执行。

{spring-data-jdbc-javadoc}org/springframework/data/relational/core/mapping/event/AfterSaveCallback.html[AfterSaveCallback]

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

Load

使用 1 个或多个 SQL 查询加载聚合。利用结果集建立聚合。

我们鼓励使用回调而不是事件,因为它们支持不变类的使用,因此比事件更强大、更有用。