Spring Data JPA 如何获取/识别底层 JPA 提供程序?
How Spring Data JPA picks up / identifies underlying JPA Provider?
我正在学习 Spring Data JPA,为此我正在编写简单的独立应用程序。这是示例代码:
实体 class --> User.java
@Entity
@Table(name="USER_DETAILS")
public class User {
@Id
@Column(name="SSNID")
private int ssnID;
@Column(name="FULLNAME")
private String fullName;
@Column(name="CITY")
private String city;
// Getters and Setters omitted
}
存储库 class --> JPADBAccess.java
@Repository
public interface JPADBAccess extends CrudRepository<User, Integer> {
}
使用存储库的简单服务 class --> DBServices.java
@Service
public class DBServices {
@Autowired(required=true)
private JPADBAccess jPADBAccess; // How does this work?? ---->(1)
public void saveUser(User user) {
User queriedUser = null;
jPADBAccess.save(user);
}
}
Spring 配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... ">
<context:annotation-config/> <!-- This enables the annotation's actions, else annotations don't do their work. -->
<context:component-scan base-package="com.example.service"/> <!-- This is for component scan -->
<jpa:repositories base-package="com.example.jpa"/> <!-- This enables support for Spring Data JPA. -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost:9092/~/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
persistence.xml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<class>com.example.model.User</class>
</persistence-unit>
独立的 classes 看起来像这样:
public class MainApp {
public static void main(String s[]) {
DBServices dBServices = null;
User user = new User();
user.setSsnID(1);
user.setCity("Blr");
user.setFullName("Full name");
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
dBServices = (DBServices) appContext.getBean("DBServices");
dBServices.saveUser(user);
}
}
现在一切正常,我使用 Hibernate 作为 JPA 提供程序(只需将 jar 放在 class 路径中).
我有以下问题:
1)当配置文件中没有定义bean时,DBService如何通过@Autowire获取JPADBAccess的实例。
@Autowired(required=true)
private JPADBAccess jPADBAccess; // How does this work?? ---->(1)
2) 当在任何配置文件中都没有提及 Hibernate 时,Spring Data JPA 如何使用或推断底层 JPA 提供程序是 Hibernate?
1) How does DBService gets the instance of JPADBAccess by @Autowire when there is no bean defined in the configuration file.
这就是 Spring Data JPA 的神奇之处:它会找到您的存储库接口并自动生成它的实现,并将其放入 Spring 应用程序上下文中。在自动装配 JPADBAccess
的 class 中,Spring 找到自动生成的实现。
2) How does Spring Data JPA uses or infers that the underlying JPA provider is Hibernate, when there is no mention of Hibernate in any of the configuration file?
但是,在 entityManagerFactory
中,您指定了一个 HibernateJpaVendorAdapter
bean。
<jpa:repositories base-package="com.example.jpa"/>
该行扫描所有存储库并为您创建 bean,在这种情况下,名为 JPADBAccess
的 bean 是由您使用 spring 数据创建的,因此您无需编写任何代码行,并添加到应用程序上下文中。
提供者的选择取决于类路径,JPA使用一些类选择提供者如下
有时会在类路径中搜索文件 META-INF/services/javax.persistence.spi.PersistenceProvider
,并且会有提供程序的名称,在您的情况下,您使用的是 HibernateJpaVendorAdapter
,而在 class code 中,您将看到将休眠加载为提供者的这一行
Class<?> hibernatePersistenceProviderClass = cl.loadClass("org.hibernate.jpa.HibernatePersistenceProvider");
我正在学习 Spring Data JPA,为此我正在编写简单的独立应用程序。这是示例代码:
实体 class --> User.java
@Entity
@Table(name="USER_DETAILS")
public class User {
@Id
@Column(name="SSNID")
private int ssnID;
@Column(name="FULLNAME")
private String fullName;
@Column(name="CITY")
private String city;
// Getters and Setters omitted
}
存储库 class --> JPADBAccess.java
@Repository
public interface JPADBAccess extends CrudRepository<User, Integer> {
}
使用存储库的简单服务 class --> DBServices.java
@Service
public class DBServices {
@Autowired(required=true)
private JPADBAccess jPADBAccess; // How does this work?? ---->(1)
public void saveUser(User user) {
User queriedUser = null;
jPADBAccess.save(user);
}
}
Spring 配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... ">
<context:annotation-config/> <!-- This enables the annotation's actions, else annotations don't do their work. -->
<context:component-scan base-package="com.example.service"/> <!-- This is for component scan -->
<jpa:repositories base-package="com.example.jpa"/> <!-- This enables support for Spring Data JPA. -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost:9092/~/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
persistence.xml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<class>com.example.model.User</class>
</persistence-unit>
独立的 classes 看起来像这样:
public class MainApp {
public static void main(String s[]) {
DBServices dBServices = null;
User user = new User();
user.setSsnID(1);
user.setCity("Blr");
user.setFullName("Full name");
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
dBServices = (DBServices) appContext.getBean("DBServices");
dBServices.saveUser(user);
}
}
现在一切正常,我使用 Hibernate 作为 JPA 提供程序(只需将 jar 放在 class 路径中).
我有以下问题:
1)当配置文件中没有定义bean时,DBService如何通过@Autowire获取JPADBAccess的实例。
@Autowired(required=true)
private JPADBAccess jPADBAccess; // How does this work?? ---->(1)
2) 当在任何配置文件中都没有提及 Hibernate 时,Spring Data JPA 如何使用或推断底层 JPA 提供程序是 Hibernate?
1) How does DBService gets the instance of JPADBAccess by @Autowire when there is no bean defined in the configuration file.
这就是 Spring Data JPA 的神奇之处:它会找到您的存储库接口并自动生成它的实现,并将其放入 Spring 应用程序上下文中。在自动装配 JPADBAccess
的 class 中,Spring 找到自动生成的实现。
2) How does Spring Data JPA uses or infers that the underlying JPA provider is Hibernate, when there is no mention of Hibernate in any of the configuration file?
但是,在 entityManagerFactory
中,您指定了一个 HibernateJpaVendorAdapter
bean。
<jpa:repositories base-package="com.example.jpa"/>
该行扫描所有存储库并为您创建 bean,在这种情况下,名为 JPADBAccess
的 bean 是由您使用 spring 数据创建的,因此您无需编写任何代码行,并添加到应用程序上下文中。
提供者的选择取决于类路径,JPA使用一些类选择提供者如下
有时会在类路径中搜索文件 META-INF/services/javax.persistence.spi.PersistenceProvider
,并且会有提供程序的名称,在您的情况下,您使用的是 HibernateJpaVendorAdapter
,而在 class code 中,您将看到将休眠加载为提供者的这一行
Class<?> hibernatePersistenceProviderClass = cl.loadClass("org.hibernate.jpa.HibernatePersistenceProvider");