Spring Boot 自动配置 : JpaRepositoriesAutoConfiguration

概述

JpaRepositoriesAutoConfigurationSpring Boot关于Spring Data JPA repository的自动配置,其主要目的是扫描和注册开发人员定义的Spring Data JPA repository bean组件。

JpaRepositoriesAutoConfiguration在如下条件满足时才生效:

  • 已经存在一个javax.sql.DataSource bean;
  • org.springframework.data.jpa.repository.JpaRepository必须存在于classpath上;
  • bean JpaRepositoryFactoryBean, JpaRepositoryConfigExtension 不存在;

    如果开发人员使用了注解@EnableJpaRepositories,该条件会失败;

  • 属性 spring.data.jpa.repositories.enabled 值为 true 或者没有被指定时才生效;

    换句话讲,缺省情况下,也就是spring.data.jpa.repositories.enabled未被使用时,相当于其值为true

JpaRepositoriesAutoConfiguration生效的时机 :

  • HibernateJpaAutoConfiguration之后;
  • TaskExecutionAutoConfiguration之后;

JpaRepositoriesAutoConfiguration应用效果 :

  • 导入JpaRepositoriesAutoConfigureRegistrar

    这是一个ImportBeanDefinitionRegistrar,可以认为JpaRepositoriesAutoConfiguration的主要效果就是靠它完成的。

  • 定义bean EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer
    • 仅在条件BootstrapExecutorCondition满足时才定义

      配置属性spring.data.jpa.repositories.bootstrap-mode明确设置为deferred或者lazy时该条件才成立

JpaRepositoriesAutoConfiguration生效时的效果和注解@EnableJpaRepositories的效果相当。在Spring Boot应用中,如果开发人员明确使用了注解@EnableJpaRepositories,JpaRepositoriesAutoConfiguration就不会应用。如果开发人员没有使用注解@EnableJpaRepositories,JpaRepositoriesAutoConfiguration才会在相应条件满足时应用。

源代码

源代码版本 : spring-boot-autoconfigure-2.1.3.RELEASE

package org.springframework.boot.autoconfigure.data.jpa;

// 省略 import 行

/**
 * EnableAutoConfiguration Auto-configuration for Spring Data's JPA Repositories.
 *
 * Activates when there is a bean of type javax.sql.DataSource configured in the
 * context, the Spring Data JPA
 * org.springframework.data.jpa.repository.JpaRepository type is on the classpath,
 * and there is no other, existing
 * org.springframework.data.jpa.repository.JpaRepository configured.
 * 
 * Once in effect, the auto-configuration is the equivalent of enabling JPA repositories
 * using the org.springframework.data.jpa.repository.config.EnableJpaRepositories
 * annotation.
 * 
 * This configuration class will activate after the Hibernate auto-configuration.
 *
 * @author Phillip Webb
 * @author Josh Long
 * @see EnableJpaRepositories
 */
@Configuration
// 仅在 bean DataSource 存在时才生效
@ConditionalOnBean(DataSource.class)
// 仅在类 JpaRepository 存在于 classpath 上时才生效
@ConditionalOnClass(JpaRepository.class)
// 仅在 bean JpaRepositoryFactoryBean, JpaRepositoryConfigExtension 不存在时才生效
@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class,
		JpaRepositoryConfigExtension.class })
// 仅在属性 spring.data.jpa.repositories.enabled 值为 true 或者没有被指定时才生效
@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", 
    havingValue = "true", matchIfMissing = true)
// 导入 JpaRepositoriesAutoConfigureRegistrar
@Import(JpaRepositoriesAutoConfigureRegistrar.class)
// 在自动配置类 HibernateJpaAutoConfiguration, TaskExecutionAutoConfiguration 应用之后应用
@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class,
		TaskExecutionAutoConfiguration.class })
public class JpaRepositoriesAutoConfiguration {

	@Bean
	@Conditional(BootstrapExecutorCondition.class)
	public EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer(
			Map<String, AsyncTaskExecutor> taskExecutors) {
		return (builder) -> {
			AsyncTaskExecutor bootstrapExecutor = determineBootstrapExecutor(
					taskExecutors);
			if (bootstrapExecutor != null) {
				builder.setBootstrapExecutor(bootstrapExecutor);
			}
		};
	}

	private AsyncTaskExecutor determineBootstrapExecutor(
			Map<String, AsyncTaskExecutor> taskExecutors) {
		if (taskExecutors.size() == 1) {
			return taskExecutors.values().iterator().next();
		}
		return taskExecutors
				.get(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME);
	}


    // 配置属性 spring.data.jpa.repositories.bootstrap-mode 明确设置为 deferred 或者 lazy 时该条件才成立
	private static final class BootstrapExecutorCondition extends AnyNestedCondition {

		BootstrapExecutorCondition() {
			super(ConfigurationPhase.REGISTER_BEAN);
		}

		@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "bootstrap-mode", 
            havingValue = "deferred", matchIfMissing = false)
		static class DeferredBootstrapMode {

		}

		@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "bootstrap-mode", 
            havingValue = "lazy", matchIfMissing = false)
		static class LazyBootstrapMode {

		}

	}

}

你可能感兴趣的:(Spring,JPA,Spring,Boot,Spring,Boot,自动配置)