JPA

Spring JPA (位於 org.springframework.orm.jpa 包下) 為 Java Persistence API 提供了全面的支援,其方式類似於與 Hibernate 的整合,同時也感知底層實現以提供附加功能。

在 Spring 環境中設定 JPA 的三種選項

Spring JPA 支援提供了三種設定 JPA EntityManagerFactory 的方式,應用程式使用 EntityManagerFactory 來獲取實體管理器。

使用 LocalEntityManagerFactoryBean

您只能在簡單的部署環境中使用此選項,例如獨立應用程式和整合測試。

LocalEntityManagerFactoryBean 建立適合簡單部署環境的 EntityManagerFactory,在這些環境中,應用程式僅使用 JPA 進行資料訪問。該工廠 Bean 使用 JPA 的 PersistenceProvider 自動檢測機制(根據 JPA 的 Java SE 引導),並且在大多數情況下,您只需要指定持久化單元名稱。下面的 XML 示例配置了這樣一個 Bean:

<beans>
	<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="myPersistenceUnit"/>
	</bean>
</beans>

這種 JPA 部署方式是最簡單且限制最多的。您無法引用現有的 JDBC DataSource Bean 定義,並且不支援全域性事務。此外,持久化類的織入(位元組碼轉換)是特定於提供商的,通常需要在啟動時指定特定的 JVM 代理。此選項僅適用於獨立應用程式和測試環境,JPA 規範正是為此設計的。

從 JNDI 獲取 EntityManagerFactory

部署到 Jakarta EE 伺服器時可以使用此選項。請查閱您的伺服器文件,瞭解如何在伺服器中部署自定義 JPA 提供商,以便使用與伺服器預設提供商不同的提供商。

從 JNDI 獲取 EntityManagerFactory(例如在 Jakarta EE 環境中)只需修改 XML 配置,如下例所示:

<beans>
	<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>

此操作假定標準的 Jakarta EE 引導流程。Jakarta EE 伺服器會自動檢測持久化單元(實際上是應用程式 Jar 包中的 META-INF/persistence.xml 檔案)以及 Jakarta EE 部署描述符(例如 web.xml)中的 persistence-unit-ref 條目,併為這些持久化單元定義環境命名上下文位置。

在這種場景下,整個持久化單元的部署(包括持久化類的織入(位元組碼轉換))由 Jakarta EE 伺服器負責。JDBC DataSource 透過 META-INF/persistence.xml 檔案中的 JNDI 位置定義。EntityManager 事務與伺服器的 JTA 子系統整合。Spring 僅使用獲取到的 EntityManagerFactory,透過依賴注入將其傳遞給應用程式物件,並管理該持久化單元的事務(通常透過 JtaTransactionManager)。

如果您在同一個應用程式中使用多個持久化單元,從 JNDI 獲取的這些持久化單元的 Bean 名稱應與應用程式引用它們時使用的持久化單元名稱相匹配(例如,在 @PersistenceUnit@PersistenceContext 註解中)。

使用 LocalContainerEntityManagerFactoryBean

您可以在基於 Spring 的應用程式環境中使用此選項,以獲得完整的 JPA 功能。這包括 Tomcat 等 Web 容器、獨立應用程式以及具有複雜持久化需求的整合測試。

LocalContainerEntityManagerFactoryBean 提供了對 EntityManagerFactory 配置的完全控制,適用於需要精細定製的環境。LocalContainerEntityManagerFactoryBean 根據 persistence.xml 檔案、提供的 dataSourceLookup 策略和指定的 loadTimeWeaver 建立一個 PersistenceUnitInfo 例項。因此,可以在 JNDI 之外使用自定義資料來源,並控制織入過程。以下示例顯示了 LocalContainerEntityManagerFactoryBean 的典型 Bean 定義:

<beans>
	<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="someDataSource"/>
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
		</property>
	</bean>
</beans>

以下示例顯示了典型的 persistence.xml 檔案:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
	<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
		<mapping-file>META-INF/orm.xml</mapping-file>
		<exclude-unlisted-classes/>
	</persistence-unit>
</persistence>
<exclude-unlisted-classes/> 快捷方式表示不應掃描帶註解的實體類。顯式設定為 'true'(<exclude-unlisted-classes>true</exclude-unlisted-classes/>)也表示不掃描。<exclude-unlisted-classes>false</exclude-unlisted-classes/> 則會觸發掃描。但是,如果您希望進行實體類掃描,我們建議省略 exclude-unlisted-classes 元素。

使用 LocalContainerEntityManagerFactoryBean 是最強大的 JPA 設定選項,允許在應用程式內進行靈活的本地配置。它支援連結到現有的 JDBC DataSource,支援本地事務和全域性事務等。但是,如果持久化提供商需要位元組碼轉換,它也對執行時環境提出了要求,例如需要具備織入能力的類載入器。

此選項可能與 Jakarta EE 伺服器的內建 JPA 功能衝突。在完整的 Jakarta EE 環境中,請考慮從 JNDI 獲取您的 EntityManagerFactory。或者,您可以在 LocalContainerEntityManagerFactoryBean 定義上指定一個自定義的 persistenceXmlLocation(例如,META-INF/my-persistence.xml),並且只在您的應用程式 Jar 檔案中包含該名稱的描述符。由於 Jakarta EE 伺服器只查詢預設的 META-INF/persistence.xml 檔案,它會忽略這些自定義的持久化單元,從而避免與 Spring 驅動的 JPA 設定發生衝突。

何時需要載入時織入(load-time weaving)?

並非所有 JPA 提供商都需要 JVM 代理。Hibernate 就是一個不需要代理的例子。如果您的提供商不需要代理,或者您有其他替代方案,例如透過自定義編譯器或 Ant 任務在構建時應用增強,則不應使用載入時織入器。

LoadTimeWeaver 介面是 Spring 提供的一個類,它允許根據環境是 Web 容器還是應用伺服器,以特定方式插入 JPA ClassTransformer 例項。透過 代理 掛接 ClassTransformer 通常效率不高。代理作用於整個虛擬機器,檢查載入的每個類,這在生產伺服器環境中通常是不希望的。

Spring 為各種環境提供了多種 LoadTimeWeaver 實現,允許 ClassTransformer 例項僅應用於每個類載入器,而不是每個虛擬機器。

關於 LoadTimeWeaver 實現及其設定(無論是通用的還是為各種平臺(如 Tomcat、JBoss 和 WebSphere)定製的)的更多資訊,請參見 AOP 章節中的 Spring 配置

Spring 配置 中所述,您可以透過使用 @EnableLoadTimeWeaving 註解或 context:load-time-weaver XML 元素來配置上下文範圍的 LoadTimeWeaver。所有 JPA LocalContainerEntityManagerFactoryBean 例項會自動檢測到這種全域性織入器。以下示例顯示了設定載入時織入器的首選方式,它提供了平臺的自動檢測(例如,Tomcat 具備織入能力的類載入器或 Spring 的 JVM 代理),並將織入器自動傳播到所有感知織入器的 Bean:

<context:load-time-weaver/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	...
</bean>

但是,如果需要,您也可以透過 loadTimeWeaver 屬性手動指定一個專用的織入器,如下例所示:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="loadTimeWeaver">
		<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
	</property>
</bean>

無論如何配置 LTW,使用此技術,依賴於 instrument 的 JPA 應用程式可以在目標平臺(例如 Tomcat)中執行,而無需代理。當宿主應用程式依賴於不同的 JPA 實現時,這一點尤其重要,因為 JPA 轉換器僅在類載入器級別應用,因此彼此隔離。

處理多個持久化單元

對於依賴於多個持久化單元位置(例如,儲存在類路徑中各種 JAR 包裡)的應用程式,Spring 提供了 PersistenceUnitManager 作為中央倉庫,以避免可能代價高昂的持久化單元發現過程。預設實現允許指定多個位置。這些位置會被解析,然後透過持久化單元名稱進行檢索。(預設情況下,會在類路徑中搜索 META-INF/persistence.xml 檔案。)以下示例配置了多個位置:

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
	<property name="persistenceXmlLocations">
		<list>
			<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
			<value>classpath:/my/package/**/custom-persistence.xml</value>
			<value>classpath*:META-INF/persistence.xml</value>
		</list>
	</property>
	<property name="dataSources">
		<map>
			<entry key="localDataSource" value-ref="local-db"/>
			<entry key="remoteDataSource" value-ref="remote-db"/>
		</map>
	</property>
	<!-- if no datasource is specified, use this one -->
	<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="persistenceUnitManager" ref="pum"/>
	<property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

預設實現允許定製 PersistenceUnitInfo 例項(在將其提供給 JPA 提供商之前),可以透過宣告方式(透過影響所有託管單元的屬性)或程式設計式方式(透過允許選擇持久化單元的 PersistenceUnitPostProcessor)進行。如果未指定 PersistenceUnitManagerLocalContainerEntityManagerFactoryBean 會在內部建立一個並使用它。

後臺引導

LocalContainerEntityManagerFactoryBean 透過 bootstrapExecutor 屬性支援後臺引導,如下例所示:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="bootstrapExecutor">
		<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
	</property>
</bean>

實際的 JPA 提供商引導過程被交給了指定的執行器,然後並行於應用程式引導執行緒執行。暴露的 EntityManagerFactory 代理可以注入到其他應用程式元件中,甚至能夠響應 EntityManagerFactoryInfo 配置檢查。但是,一旦實際的 JPA 提供商被其他元件訪問(例如,呼叫 createEntityManager),這些呼叫將阻塞,直到後臺引導完成。特別是當您使用 Spring Data JPA 時,請確保也為其倉庫設定了延遲引導。

自 6.2 版本起,JPA 初始化在上下文重新整理完成之前強制執行,在此之前等待非同步引導完成。這使得完全初始化的資料庫基礎設施的可用性變得可預測,並允許在 ContextRefreshedEvent 監聽器等地方編寫自定義的初始化後邏輯。不建議將此類應用程式級別的資料庫初始化放入 @PostConstruct 方法或類似位置;最好將其放在 Lifecycle.start(如果適用)或 ContextRefreshedEvent 監聽器中。

基於 JPA 實現 DAO:EntityManagerFactoryEntityManager

儘管 EntityManagerFactory 例項是執行緒安全的,但 EntityManager 例項不是。注入的 JPA EntityManager 的行為類似於從應用伺服器的 JNDI 環境中獲取的 EntityManager,如 JPA 規範所定義。它將所有呼叫委託給當前的事務性 EntityManager(如果存在)。否則,它會回退到為每個操作新建立的 EntityManager,實際上使其使用是執行緒安全的。

透過使用注入的 EntityManagerFactoryEntityManager,可以編寫純粹基於 JPA 且不依賴於 Spring 的程式碼。如果啟用了 PersistenceAnnotationBeanPostProcessor,Spring 可以理解欄位和方法級別的 @PersistenceUnit@PersistenceContext 註解。以下示例展示了一個使用 @PersistenceUnit 註解的純粹 JPA DAO 實現:

  • Java

  • Kotlin

public class ProductDaoImpl implements ProductDao {

	private EntityManagerFactory emf;

	@PersistenceUnit
	public void setEntityManagerFactory(EntityManagerFactory emf) {
		this.emf = emf;
	}

	public Collection loadProductsByCategory(String category) {
		EntityManager em = this.emf.createEntityManager();
		try {
			Query query = em.createQuery("from Product as p where p.category = ?1");
			query.setParameter(1, category);
			return query.getResultList();
		}
		finally {
			if (em != null) {
				em.close();
			}
		}
	}
}
class ProductDaoImpl : ProductDao {

	private lateinit var emf: EntityManagerFactory

	@PersistenceUnit
	fun setEntityManagerFactory(emf: EntityManagerFactory) {
		this.emf = emf
	}

	fun loadProductsByCategory(category: String): Collection<*> {
		val em = this.emf.createEntityManager()
		val query = em.createQuery("from Product as p where p.category = ?1");
		query.setParameter(1, category);
		return query.resultList;
	}
}

前面的 DAO 不依賴於 Spring,並且仍然很好地融入了 Spring 應用程式上下文。此外,該 DAO 利用註解來要求注入預設的 EntityManagerFactory,如下面的 Bean 定義示例所示:

<beans>

	<!-- bean post-processor for JPA annotations -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

作為顯式定義 PersistenceAnnotationBeanPostProcessor 的替代方案,可以考慮在應用程式上下文配置中使用 Spring 的 context:annotation-config XML 元素。這樣做會自動註冊所有 Spring 標準的基於註解配置的後處理器,包括 CommonAnnotationBeanPostProcessor 等。

考慮以下示例:

<beans>

	<!-- post-processors for all standard config annotations -->
	<context:annotation-config/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

這種 DAO 的主要問題在於它總是透過工廠建立一個新的 EntityManager。您可以避免這種情況,方法是請求注入一個事務性 EntityManager(也稱為“共享 EntityManager”,因為它是一個共享的、執行緒安全的代理,用於實際的事務性 EntityManager),而不是工廠。以下示例展示瞭如何這樣做:

  • Java

  • Kotlin

public class ProductDaoImpl implements ProductDao {

	@PersistenceContext
	private EntityManager em;

	public Collection loadProductsByCategory(String category) {
		Query query = em.createQuery("from Product as p where p.category = :category");
		query.setParameter("category", category);
		return query.getResultList();
	}
}
class ProductDaoImpl : ProductDao {

	@PersistenceContext
	private lateinit var em: EntityManager

	fun loadProductsByCategory(category: String): Collection<*> {
		val query = em.createQuery("from Product as p where p.category = :category")
		query.setParameter("category", category)
		return query.resultList
	}
}

@PersistenceContext 註解有一個可選屬性 type,其預設值為 PersistenceContextType.TRANSACTION。您可以使用此預設值來接收共享的 EntityManager 代理。另一種替代方案 PersistenceContextType.EXTENDED 是完全不同的情況。這會產生一個所謂的擴充套件 EntityManager,它不是執行緒安全的,因此不得在併發訪問的元件中使用,例如 Spring 管理的單例 Bean。擴充套件的 EntityManager 例項僅應在有狀態元件中使用,例如駐留在會話中,其 EntityManager 的生命週期不繫結到當前事務,而是完全由應用程式決定。

方法和欄位級別的注入

您可以將表示依賴注入的註解(例如 @PersistenceUnit@PersistenceContext)應用於類中的欄位或方法——因此有了“方法級別注入”和“欄位級別注入”的說法。欄位級別的註解簡潔易用,而方法級別的註解允許對注入的依賴項進行進一步處理。在這兩種情況下,成員的可訪問性(public、protected 或 private)都不重要。

類級別註解呢?

在 Jakarta EE 平臺上,它們用於依賴項宣告,而不是資源注入。

注入的 EntityManager 是 Spring 管理的(感知當前正在進行的事務)。即使新的 DAO 實現使用方法級別注入 EntityManager 而不是 EntityManagerFactory,由於使用了註解,Bean 定義中也不需要進行更改。

這種 DAO 風格的主要優點是它只依賴於 Java Persistence API。無需匯入任何 Spring 類。此外,由於 Spring 容器能夠理解 JPA 註解,注入會自動應用。從非侵入性的角度來看,這很有吸引力,並且對 JPA 開發者來說可能感覺更自然。

基於 @Autowired 實現 DAO(通常結合建構函式注入)

@PersistenceUnit@PersistenceContext 只能在方法和欄位上宣告。那麼,透過建構函式和其他 @Autowired 注入點提供 JPA 資源呢?

只要目標被定義為一個 Bean(例如,透過 LocalContainerEntityManagerFactoryBean),就可以輕鬆地透過建構函式和 @Autowired 欄位/方法注入 EntityManagerFactory。注入點按型別原樣匹配原始的 EntityManagerFactory 定義。

然而,@PersistenceContext 風格的共享 EntityManager 引用並非開箱即用地可用於常規依賴注入。為了使其能夠進行 @Autowired 所需的型別匹配,請考慮為您的 EntityManagerFactory 定義 companion 定義一個 SharedEntityManagerBean

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	...
</bean>

<bean id="em" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
	<property name="entityManagerFactory" ref="emf"/>
</bean>

或者,您可以基於 SharedEntityManagerCreator 定義一個 @Bean 方法:

@Bean("em")
public static EntityManager sharedEntityManager(EntityManagerFactory emf) {
	return SharedEntityManagerCreator.createSharedEntityManager(emf);
}

如果有多個持久化單元,每個 EntityManagerFactory 定義都需要附帶一個相應的 EntityManager Bean 定義,最好使用與不同的 EntityManagerFactory 定義匹配的限定符(Qualifier),以便透過 @Autowired @Qualifier("…​") 來區分這些持久化單元。

Spring 驅動的 JPA 事務

我們強烈建議您閱讀 宣告式事務管理(如果您尚未閱讀),以更詳細地瞭解 Spring 的宣告式事務支援。

對於 JPA 而言,推薦的策略是利用 JPA 的原生事務支援實現的本地事務。Spring 的 JpaTransactionManager 對任何常規 JDBC 連線池提供了許多本地 JDBC 事務已知的能力(例如事務特定的隔離級別和資源層只讀最佳化),而無需 JTA 事務協調器和支援 XA 的資源。

Spring JPA 還允許已配置的 JpaTransactionManager 將 JPA 事務暴露給訪問同一 DataSource 的 JDBC 訪問程式碼,前提是註冊的 JpaDialect 支援檢索底層的 JDBC Connection。Spring 為 EclipseLink 和 Hibernate JPA 實現提供了方言。有關 JpaDialect 的詳細資訊,請參閱下一節

對於 JTA 風格的實際資源連線的延遲檢索,Spring 為目標連線池提供了相應的 DataSource 代理類:請參閱LazyConnectionDataSourceProxy。這對於 JPA 只讀事務尤其有用,因為只讀事務通常可以從本地快取處理,而無需訪問資料庫。

理解 JpaDialectJpaVendorAdapter

作為一項高階特性,JpaTransactionManagerAbstractEntityManagerFactoryBean 的子類允許將自定義的 JpaDialect 傳遞到 jpaDialect bean 屬性中。JpaDialect 實現可以啟用 Spring 支援的以下高階特性,通常是以特定於供應商的方式

  • 應用特定的事務語義(例如自定義隔離級別或事務超時)

  • 檢索事務性 JDBC Connection(用於暴露給基於 JDBC 的 DAO)

  • PersistenceException 到 Spring 的 DataAccessException 的高階轉換

這對於特殊的事務語義和高階異常轉換特別有價值。預設實現(DefaultJpaDialect)不提供任何特殊能力,如果需要前面列出的特性,則必須指定適當的方言。

作為一項更廣泛的提供商適應設施,主要用於 Spring 全功能 LocalContainerEntityManagerFactoryBean 設定,JpaVendorAdapter 結合了 JpaDialect 的能力與其他提供商特定的預設設定。指定 HibernateJpaVendorAdapterEclipseLinkJpaVendorAdapter 分別是為 Hibernate 或 EclipseLink 自動配置 EntityManagerFactory 設定最方便的方式。請注意,這些提供商介面卡主要設計用於 Spring 驅動的事務管理(即,與 JpaTransactionManager 一起使用)。

有關 JpaDialectJpaVendorAdapter 的操作及其在 Spring JPA 支援中的使用方式的更多詳細資訊,請參閱其 JpaDialectJpaVendorAdapter 的 Javadoc。

使用 JTA 事務管理設定 JPA

作為 JpaTransactionManager 的替代方案,Spring 還允許透過 JTA 進行多資源事務協調,無論是在 Jakarta EE 環境中,還是使用獨立的事務協調器(如 Atomikos)。除了選擇 Spring 的 JtaTransactionManager 而不是 JpaTransactionManager 之外,您還需要採取幾個進一步的步驟

  • 底層的 JDBC 連線池需要支援 XA 並與您的事務協調器整合。這在 Jakarta EE 環境中通常很簡單,透過 JNDI 暴露不同型別的 DataSource。有關詳細資訊,請參閱您的應用伺服器文件。類似地,獨立的事務協調器通常自帶特殊的 XA 整合 DataSource 變體。同樣,請查閱其文件。

  • JPA EntityManagerFactory 設定需要配置為支援 JTA。這是特定於提供商的,通常透過在 LocalContainerEntityManagerFactoryBean 上指定特殊屬性作為 jpaProperties 來實現。對於 Hibernate,這些屬性甚至與版本相關。有關詳細資訊,請參閱您的 Hibernate 文件。

  • Spring 的 HibernateJpaVendorAdapter 強制執行某些面向 Spring 的預設設定,例如連線釋放模式 on-close,這與 Hibernate 5.0 中 Hibernate 自己的預設設定匹配,但在 Hibernate 5.1+ 中不再匹配。對於 JTA 設定,請確保將您的持久單元事務型別宣告為 "JTA"。或者,將 Hibernate 5.2 的 hibernate.connection.handling_mode 屬性設定為 DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT 以恢復 Hibernate 自己的預設設定。有關相關說明,請參閱使用 Hibernate 出現虛假的應用伺服器警告

  • 或者,考慮從您的應用伺服器本身獲取 EntityManagerFactory(即,透過 JNDI 查詢而不是本地宣告的 LocalContainerEntityManagerFactoryBean)。伺服器提供的 EntityManagerFactory 可能需要在您的伺服器配置中進行特殊定義(使部署的可移植性降低),但它是為伺服器的 JTA 環境設定的。

原生 Hibernate 設定和原生 Hibernate 事務用於 JPA 互動

原生 LocalSessionFactoryBean 設定與 HibernateTransactionManager 結合使用,可以與 @PersistenceContext 和其他 JPA 訪問程式碼進行互動。Hibernate SessionFactory 現在原生實現了 JPA 的 EntityManagerFactory 介面,而 Hibernate Session 控制代碼原生就是 JPA EntityManager。Spring 的 JPA 支援設施會自動檢測原生 Hibernate 會話。

因此,這種原生 Hibernate 設定可以在許多場景中作為標準 JPA LocalContainerEntityManagerFactoryBeanJpaTransactionManager 組合的替代方案,允許在同一本地事務中與 SessionFactory.getCurrentSession()(以及 HibernateTemplate)以及 @PersistenceContext EntityManager 進行互動。這種設定還提供了更強大的 Hibernate 整合和更高的配置靈活性,因為它不受 JPA 引導契約的限制。

在這種情況下,您不需要 HibernateJpaVendorAdapter 配置,因為 Spring 的原生 Hibernate 設定提供了更多特性(例如,自定義 Hibernate Integrator 設定,Hibernate 5.3 bean 容器整合,以及更強大的只讀事務最佳化)。最後但同樣重要的是,您還可以透過 LocalSessionFactoryBuilder 表達原生 Hibernate 設定,與 @Bean 風格的配置無縫整合(不涉及 FactoryBean)。

LocalSessionFactoryBeanLocalSessionFactoryBuilder 支援後臺引導,就像 JPA LocalContainerEntityManagerFactoryBean 一樣。有關介紹,請參閱後臺引導

LocalSessionFactoryBean 上,這可以透過 bootstrapExecutor 屬性獲得。在程式設計方式的 LocalSessionFactoryBuilder 上,過載的 buildSessionFactory 方法接受一個引導執行器引數。