在上一節(jié)中赂苗,我們簡單的講述了jpa的查詢語法和使用教程,而這一節(jié)咱們來看看Spring Boot中對jpa是如何進(jìn)行自動配置的贮尉。
?
在Spring Boot自動配置的時候拌滋,一旦引入spring-boot-starter-data-jpa,就會完成
JpaRepositoriesAutoConfiguration的自動配置猜谚。
JpaRepositoriesAutoConfiguration
@Configuration
@ConditionalOnBean(DataSource.class)
@ConditionalOnClass(JpaRepository.class)
@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class,
JpaRepositoryConfigExtension.class })
@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(JpaRepositoriesAutoConfigureRegistrar.class)
@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)
public class JpaRepositoriesAutoConfiguration {}
spring-data-jpa底層使用的是Hibernate作為實現(xiàn)败砂,所以jpa的自動配置操作在Hibernate的自動配置之后。
@AutoConfigureAfter:表示在指定類完成后再進(jìn)行自動配置魏铅,所以來看HibernateJpaAutoConfiguration源碼昌犹。
咱們繼續(xù):
HibernateJpaAutoConfiguration
@Configuration
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class })
@Conditional(HibernateEntityManagerCondition.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
//other...
public HibernateJpaAutoConfiguration(DataSource dataSource,
JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
//調(diào)用父類的構(gòu)造方法
super(dataSource, jpaProperties, jtaTransactionManager,
transactionManagerCustomizers);
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties() {
Map<String, Object> vendorProperties = new LinkedHashMap<String, Object>();
vendorProperties.putAll(getProperties().getHibernateProperties(getDataSource()));
return vendorProperties;
}
//other...
}
同樣在HibernateJpaAutoConfiguration的源碼中表示該自動配置需要在DataSourceAutoConfiguration完成后再進(jìn)行,之前在分析JdbcTemplateAutoConfiguration的源碼的時候已經(jīng)分析過DataSourceAutoConfiguration览芳,此處就不再講述斜姥,一筆帶過。
? 回想之前在使用Spring和JPA集成的時候沧竟,會配置一個jpaVendorAdapter屬性铸敏,一般使用HibernateJpaVendorAdapter作為JPA持久化實現(xiàn)廠商類。如下是spring和jpa集成時的部分配置:
<property name="jpaVendorAdapter">
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 該bean的屬性配置 -->
</bean>
</property>
? 在JpaBaseConfiguration類中有個createJpaVendorAdapter()抽象方法悟泵,而在HibernateJpaAutoConfiguration類中進(jìn)行了重載杈笔,創(chuàng)建使用HibernateJpaVendorAdapter作為JPA底層持久化實現(xiàn)廠商。
咱們來看父類的源碼:
父類JpaBaseConfiguration
@EnableConfigurationProperties(JpaProperties.class)
@Import(DataSourceInitializedPublisher.Registrar.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
private final DataSource dataSource;
private final JpaProperties properties;
private final JtaTransactionManager jtaTransactionManager;
private final TransactionManagerCustomizers transactionManagerCustomizers;
private ConfigurableListableBeanFactory beanFactory;
protected JpaBaseConfiguration(DataSource dataSource, JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
this.dataSource = dataSource;
this.properties = properties;
this.jtaTransactionManager = jtaTransactionManager.getIfAvailable();
this.transactionManagerCustomizers = transactionManagerCustomizers
.getIfAvailable();
}
//創(chuàng)建了TransactionManager的Bean
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
//創(chuàng)建了jpaVendorAdapter適配器糕非,并填充相應(yīng)屬性蒙具,最后返回
@Bean
@ConditionalOnMissingBean
public JpaVendorAdapter jpaVendorAdapter() {
//通過HibernateJpaAutoConfiguration子類創(chuàng)建HibernateJpaVendorAdapter適配器
AbstractJpaVendorAdapter adapter = createJpaVendorAdapter();
adapter.setShowSql(this.properties.isShowSql());
adapter.setDatabase(this.properties.determineDatabase(this.dataSource));
adapter.setDatabasePlatform(this.properties.getDatabasePlatform());
adapter.setGenerateDdl(this.properties.isGenerateDdl());
return adapter;
}
//通過jpaVendorAdapter與其他配置信息創(chuàng)建Builder構(gòu)建器
@Bean
@ConditionalOnMissingBean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(
JpaVendorAdapter jpaVendorAdapter,
ObjectProvider<PersistenceUnitManager> persistenceUnitManager) {
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(
jpaVendorAdapter, this.properties.getProperties(),
persistenceUnitManager.getIfAvailable());
builder.setCallback(getVendorCallback());
return builder;
}
//創(chuàng)建LocalContainerEntityManagerFactoryBean的Bean,用于JPA的容器管理EntityManagerFactory
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class,
EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder factoryBuilder) {
Map<String, Object> vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan())
.properties(vendorProperties).jta(isJta()).build();
}
//other...
}
在父類JpaBaseConfiguration中創(chuàng)建了幾個重要的Bean朽肥,這樣創(chuàng)建Bean的過程類似之前spring-jpa集成時使用的xml配置文件:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
<!-- 配置jpa的EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 配置jpa生產(chǎn)商的適配器 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<!-- 配置jpa的基本屬性 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 配置SpringData -->
<jpa:repositories base-package="xxxxx包名" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"></jpa:repositories>
通過這幾步j(luò)ava配置禁筏,基本上就完成了之前spring-jpa集成所需的所有配置信息,當(dāng)然Spring Boot內(nèi)部做了很多工作鞠呈,這里就不再描述了融师。