生命週期事件

Spring Data JDBC 發布生命週期事件到 ApplicationListener 物件,通常是應用程式內容中的 beans。事件是關於特定生命週期階段的通知。與實體回呼相反,事件旨在用於通知。事務性監聽器將在事務完成時接收事件。事件和回呼僅針對聚合根觸發。如果您想處理非根實體,您需要通過包含聚合根的監聽器來執行此操作。

實體生命週期事件可能成本高昂,並且當載入大型結果集時,您可能會注意到效能配置文件的變化。您可以在 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());
	}
}

下表描述了可用的事件。有關處理步驟之間確切關係的更多詳細資訊,請參閱 可用回呼的描述,它們與事件 1:1 對應。

表 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

在聚合根被儲存之後(即,插入或更新)。

載入

使用 1 個或多個 SQL 查詢載入聚合。從結果集建構聚合。

AfterConvertCallback

我們鼓勵使用回呼而不是事件,因為它們支援使用不可變的類別,因此比事件更強大且更通用。