概述
JpaRepositoriesAutoConfiguration
是Spring 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 {
}
}
}