【Spring Boot】(28)、Spring Boot中spring-data-jpa自动配置源码分析

在上一节中,我们简单的讲述了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内部做了很多工作,这里就不再描述了。

 

本章节讲述原理,比较抽象,如有讲述不清晰或者不理解的,还请各位担待,有问题可以加我,咱们一起讨论,谢谢啦!

 

 

====================打个广告,欢迎关注====================

QQ: 412425870
微信公众号:Cay课堂 【Spring Boot】(28)、Spring Boot中spring-data-jpa自动配置源码分析_第1张图片
csdn博客: http://blog.csdn.net/caychen
码云: https://gitee.com/caychen/
github: https://github.com/caychen

点击群号或者扫描二维码即可加入QQ群:

328243383(1群)

 

点击群号或者扫描二维码即可加入QQ群:

180479701(2群)

 

 

 

 

你可能感兴趣的:(Java,Spring,Boot,Spring,Boot技术)