[Spring Boot] Spring-data-jpa automatic configuration source code analysis in Spring Boot

In the previous section, we briefly described the query syntax and usage tutorial of jpa, and in this section, let's take a look at how jpa is automatically configured in Spring Boot.

    

When Spring Boot is auto-configured, once it is introduced , the auto-configuration will be completed .spring-boot-starter-data-jpaJpaRepositoriesAutoConfiguration


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 {}

The bottom layer of spring-data-jpa uses Hibernate as the implementation, so the automatic configuration of jpa is after the automatic configuration of Hibernate.

@AutoConfigureAfter : Indicates that automatic configuration is performed after the specified class is completed, so look at the HibernateJpaAutoConfiguration source code.

Let's continue:

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) {
        //call the constructor of the parent class
		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...
}

Also in the source code of HibernateJpaAutoConfiguration , it is indicated that the automatic configuration needs to be done after the completion of DataSourceAutoConfiguration . Before analyzing the source code of JdbcTemplateAutoConfiguration , DataSourceAutoConfiguration has been analyzed , so I won't talk about it here, but I will take it for a while.

    Recall that when using Spring to integrate with JPA, a jpaVendorAdapter property will be configured. Generally, HibernateJpaVendorAdapter is used as the JPA persistence implementation vendor class. The following is part of the configuration when spring and jpa are integrated:

<property name="jpaVendorAdapter">
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <!-- Property configuration of the bean -->
    </bean>
</property>

There is a createJpaVendorAdapter() abstract method     in the JpaBaseConfiguration class, and it is overloaded in the HibernateJpaAutoConfiguration class to create and use HibernateJpaVendorAdapter as the JPA bottom layer persistence implementation vendor.


Let's look at the source code of the parent class:

Parent class 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();
	}

    //Create a Bean of TransactionManager
	@Bean
	@ConditionalOnMissingBean(PlatformTransactionManager.class)
	public PlatformTransactionManager transactionManager() {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		if (this.transactionManagerCustomizers != null) {
			this.transactionManagerCustomizers.customize(transactionManager);
		}
		return transactionManager;
	}

    //Create a jpaVendorAdapter adapter, fill in the corresponding properties, and finally return
	@Bean
	@ConditionalOnMissingBean
	public JpaVendorAdapter jpaVendorAdapter() {
        //Create HibernateJpaVendorAdapter adapter through HibernateJpaAutoConfiguration subclass
		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;
	}

    //Create a Builder builder with jpaVendorAdapter and other configuration information
	@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;
	}

    //Create a Bean of LocalContainerEntityManagerFactoryBean for JPA container management 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...
}

Several important beans are created in the parent class JpaBaseConfiguration , so that the process of creating beans is similar to the xml configuration file used in the previous spring-jpa integration:

<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>

<!-- Configure jpa's EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"></property>

    <!-- configure the jpa manufacturer's adapter -->
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
    </property>

    <!-- Configure the basic properties of 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>

<!-- Configure SpringData -->
<jpa:repositories base-package="xxxxx包名" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"></jpa:repositories>

Through these steps of java configuration, all the configuration information required for the previous spring-jpa integration is basically completed. Of course, Spring Boot has done a lot of work internally, so I won't describe it here.


This chapter describes the principle and is relatively abstract. If the description is unclear or unclear, please bear with me. If you have any questions, you can add me and let’s discuss together, thank you!


=====================Make an advertisement, welcome to pay attention =====================

QQ:
412425870
WeChat public account: Cay Classroom

csdn blog:
http://blog.csdn.net/caychen
Code cloud:
https://gitee.com/caychen/
github:
https://github.com/caychen

Click on the group number or scan the QR code to join the QQ group:

328243383 (1 group)




Click on the group number or scan the QR code to join the QQ group:

180479701 (2 groups)





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325587999&siteId=291194637