在上一节中,我们简单的讲述了jpa的查询语法和使用教程,而这一节咱们来看看Spring Boot中对jpa是如何进行自动配置的。
在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作为实现,所以jpa的自动配置操作在Hibernate的自动配置之后。
@AutoConfigureAfter:表示在指定类完成后再进行自动配置,所以来看HibernateJpaAutoConfiguration源码。
咱们继续:
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,
ObjectProvider transactionManagerCustomizers) {
//调用父类的构造方法
super(dataSource, jpaProperties, jtaTransactionManager,
transactionManagerCustomizers);
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Override
protected Map getVendorProperties() {
Map vendorProperties = new LinkedHashMap();
vendorProperties.putAll(getProperties().getHibernateProperties(getDataSource()));
return vendorProperties;
}
//other...
}
同样在HibernateJpaAutoConfiguration的源码中表示该自动配置需要在DataSourceAutoConfiguration完成后再进行,之前在分析JdbcTemplateAutoConfiguration的源码的时候已经分析过DataSourceAutoConfiguration,此处就不再讲述,一笔带过。
回想之前在使用Spring和JPA集成的时候,会配置一个jpaVendorAdapter属性,一般使用HibernateJpaVendorAdapter作为JPA持久化实现厂商类。如下是spring和jpa集成时的部分配置:
在JpaBaseConfiguration类中有个createJpaVendorAdapter()抽象方法,而在HibernateJpaAutoConfiguration类中进行了重载,创建使用HibernateJpaVendorAdapter作为JPA底层持久化实现厂商。
咱们来看父类的源码:
父类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,
ObjectProvider transactionManagerCustomizers) {
this.dataSource = dataSource;
this.properties = properties;
this.jtaTransactionManager = jtaTransactionManager.getIfAvailable();
this.transactionManagerCustomizers = transactionManagerCustomizers
.getIfAvailable();
}
//创建了TransactionManager的Bean
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
//创建了jpaVendorAdapter适配器,并填充相应属性,最后返回
@Bean
@ConditionalOnMissingBean
public JpaVendorAdapter jpaVendorAdapter() {
//通过HibernateJpaAutoConfiguration子类创建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与其他配置信息创建Builder构建器
@Bean
@ConditionalOnMissingBean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(
JpaVendorAdapter jpaVendorAdapter,
ObjectProvider persistenceUnitManager) {
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(
jpaVendorAdapter, this.properties.getProperties(),
persistenceUnitManager.getIfAvailable());
builder.setCallback(getVendorCallback());
return builder;
}
//创建LocalContainerEntityManagerFactoryBean的Bean,用于JPA的容器管理EntityManagerFactory
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class,
EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder factoryBuilder) {
Map vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan())
.properties(vendorProperties).jta(isJta()).build();
}
//other...
}
在父类JpaBaseConfiguration中创建了几个重要的Bean,这样创建Bean的过程类似之前spring-jpa集成时使用的xml配置文件:
true
true
update
通过这几步java配置,基本上就完成了之前spring-jpa集成所需的所有配置信息,当然Spring Boot内部做了很多工作,这里就不再描述了。