我讀到“JPA 只是規范,而不是實作”和“Hibernate 是 JPA 的實作”。但是我不明白它們在執行程式時是如何組合在一起的。讓我一步一步解釋我的意思:
我在我的 pom 中放置了兩個依賴項:
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
對于 JPA 的東西(類、注釋)和
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.11</version>
</dependency>
用于實施。
我準備了帶有設定的 persistence.xml 檔案,我在其中表示我想使用 Hibernate
<persistence-unit name="dvdPU">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/dvdrental" />
<property name="jakarta.persistence.jdbc.user" value="postgres" />
<property name="jakarta.persistence.jdbc.password" value="j123" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
</persistence-unit>
然后我寫
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
...
final EntityManagerFactory factory = Persistence.createEntityManagerFactory("dvdPU");
final EntityManager manager = factory.createEntityManager();
正如你所看到的——這段代碼中還沒有提到 Hibernate,只是 javax.persistence 包。這是否意味著 JPA 包中的這個 Persistence 類確實實作了一些引導程式,從而導致程式理解使用 Hibernate?這也意味著 JPA 不僅僅是“規范”,它還有一些實作嗎?
uj5u.com熱心網友回復:
將javax.persistence-api(或jakarta.persistence-api)視為可以切換底層實作的外觀。就像 logging 門面一樣slf4j。Slf4j 也帶有它自己的類。它不僅僅是一個理論規范。它可能帶有一組定義合同的介面甚至類。
如果您檢查 的來源Persistence.createEntityManagerFactory("dvdPU");,您會看到它將通過決議器搜索 persistenceProvider。
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
EntityManagerFactory emf = null;
PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();
List<PersistenceProvider> providers = resolver.getPersistenceProviders();
決議器將在運行時環境中搜索所有實作javax.persistence.spi.PersistenceProvider(舊版本)或jakarta.persistence.spi.PersistenceProvider(新版本)介面的類。因為您在類路徑上有 Hibernate,所以org.hibernate.jpa.HibernatePersistenceProvider會檢測到并使用它。如果您使用 eclipselink 并將其放在類路徑中,org.eclipse.persistence.jpa.PersistenceProvider則將使用它。
當然,您也可以選擇將 Provider 顯式系結到持久性單元。當您在類路徑上有多個時,這可能是最佳選擇。
請注意,規范列出了這些介面和類。
鏈接到ProviderChecker javadoc。具體參見“描述符和/或集成請求 Hibernate 作為 PersistenceProvider 嗎?請注意,在沒有命名請求的提供者的情況下,我們假設我們是提供者(呼叫以某種方式到達我們......)”。
uj5u.com熱心網友回復:
javax.persistence.Persistence是一個類,而不是一個介面,并且您將您在 XML 組態檔中定義的持久性單元的名稱傳遞給它的建構式,您在該檔案中宣告要使用 Hibernate。所以這里發生的事情就像你假設的那樣:你的組態檔正在被讀取,并且 Hibernate 被使用,因為你配置了一些東西,所以它會被使用。javax.persistence.Persistence 您可以在此處找到源代碼并親自查看它的作用(您可能需要檢查其他類以獲取讀取 XML 配置的實際部分)。
uj5u.com熱心網友回復:
作為規范和 API,并不排除 API 具有一些具體的類。在此背景關系中,“實施”一詞的意思是“本規范的實施”。JPA API 不是 JPA 規范的實作,Hibernate 和 EclipseLink 等庫是一種實作。
這也適用于其他規范。例如,JDBC 有許多具體的類(最重要的是DriverManager),但這并不意味著 JDBC API 本身就是一個實作。JDBC 驅動程式是 JDBC 規范的一種實作。
我想您會發現 Java 生態系統中許多規范的 API 都有一個或多個具體的類,這些類提供引導、查找或其他服務,以使實際的實作可發現和可用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/495696.html
