/**
* 在org.springframework.boot.autoconfigure包的spring.factories文件中
* 导入了JpaRepositoriesAutoConfiguration和HibernateJpaAutoConfiguration
*/
@Configuration(proxyBeanMethods = false)
// 必须存在DataSource
@ConditionalOnBean(DataSource.class)
// 必须存在JpaRepository
@ConditionalOnClass(JpaRepository.class)
// 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)
// 导入JpaRepositoriesRegistrar,这个类主要就是为了开启@EnableJpaRepositories注解
@Import(JpaRepositoriesRegistrar.class)
// 在HibernateJpaAutoConfiguration和TaskExecutionAutoConfiguration类之后加载
@AutoConfigureAfter({HibernateJpaAutoConfiguration.class, TaskExecutionAutoConfiguration.class})
public class JpaRepositoriesAutoConfiguration {
/**
* 创建EntityManagerFactory的Builder对象
*/
@Bean
@ConditionalOnMissingBean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, ObjectProvider<PersistenceUnitManager> persistenceUnitManager, ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) {
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter, this.properties.getProperties(), persistenceUnitManager.getIfAvailable());
// 使用自定义处理器对EntityManagerFactoryBuilder进行自定义
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}
/**
* 对EntityManagerFactoryBuilder进行自定义配置的类
*/
@Bean
@Conditional(BootstrapExecutorCondition.class)
public EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer(Map<String, AsyncTaskExecutor> taskExecutors) {
return (builder) -> {
AsyncTaskExecutor bootstrapExecutor = determineBootstrapExecutor(taskExecutors);
if (bootstrapExecutor != null) {
builder.setBootstrapExecutor(bootstrapExecutor);
}
};
}
/**
* JPA供应商的配置
*/
@Bean
@ConditionalOnMissingBean
public JpaVendorAdapter jpaVendorAdapter() {
AbstractJpaVendorAdapter adapter = createJpaVendorAdapter();
adapter.setShowSql(this.properties.isShowSql());
if (this.properties.getDatabase() != null) {
adapter.setDatabase(this.properties.getDatabase());
}
if (this.properties.getDatabasePlatform() != null) {
adapter.setDatabasePlatform(this.properties.getDatabasePlatform());
}
adapter.setGenerateDdl(this.properties.isGenerateDdl());
return adapter;
}
/**
* 配置LocalContainerEntityManagerFactoryBean,Hirbernate整合Spring的EntityManagerFactory生成器
*/
@Bean
@Primary
@ConditionalOnMissingBean({LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class})
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
// 获取供应商配置
Map<String, Object> vendorProperties = getVendorProperties();
// 自定义配置
customizeVendorProperties(vendorProperties);
// 构建LocalContainerEntityManagerFactoryBean对象
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties).mappingResources(getMappingResources()).jta(isJta()).build();
}
/**
* 处理spring.jpa.open-in-view的逻辑
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(WebMvcConfigurer.class)
@ConditionalOnMissingBean({OpenEntityManagerInViewInterceptor.class, OpenEntityManagerInViewFilter.class})
@ConditionalOnMissingFilterBean(OpenEntityManagerInViewFilter.class)
@ConditionalOnProperty(prefix = "spring.jpa", name = "open-in-view", havingValue = "true", matchIfMissing = true)
protected static class JpaWebConfiguration {
private final JpaProperties jpaProperties;
protected JpaWebConfiguration(JpaProperties jpaProperties) {
this.jpaProperties = jpaProperties;
}
@Bean
public OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
// 给定一个拦截器
// 拦截器解释,是处理open-in-veiw的逻辑,请求一创建就保存EntityManager对象到当前线程中
// 也就是为了延长事务的生命周期,整个请求使用同一个事务
return new OpenEntityManagerInViewInterceptor();
}
/**
* 添加处理open-iv-view的逻辑拦截器
*/
@Bean
public WebMvcConfigurer openEntityManagerInViewInterceptorConfigurer(OpenEntityManagerInViewInterceptor interceptor) {
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addWebRequestInterceptor(interceptor);
}
};
}
}
// 拦截器解释,是处理open-in-veiw的逻辑,请求一创建就保存EntityManager对象到当前线程中
// 也就是为了延长事务的生命周期,整个请求使用同一个事务
class OpenEntityManagerInViewInterceptor implements AsyncWebRequestInterceptor {
// 请求之前,将EntityManagerHolder绑定到当前线程
public void preHandle(WebRequest request) throws DataAccessException {
// 获取存入request域的属性名
String key = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
// 获取EntityManagerFactory
EntityManagerFactory emf = obtainEntityManagerFactory();
// 如果当前线程已经绑定了EntityManagerFactory对应的EntityManagerHolder
if (TransactionSynchronizationManager.hasResource(emf)) {
// 获取请求域中存入的数量,引用了多少次
Integer count = (Integer) request.getAttribute(key, WebRequest.SCOPE_REQUEST);
// 数量加+
int newCount = (count != null ? count + 1 : 1);
// 将数量存入请求域中
request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
} else {
// 如果没有绑定到当前线程
try {
// 创建EntityManager
EntityManager em = createEntityManager();
// 创建EntityManagerHolder
EntityManagerHolder emHolder = new EntityManagerHolder(em);
// 绑定到当前线程
TransactionSynchronizationManager.bindResource(emf, emHolder);
// 创建拦截器
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
// 注册回调拦截器
asyncManager.registerCallableInterceptor(key, interceptor);
// 注册延迟的结果拦截器
asyncManager.registerDeferredResultInterceptor(key, interceptor);
} catch (PersistenceException ex) {
throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
}
}
}
// 请求之后
public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException {
// 如果EntityManagerHolder没准引用了
if (!decrementParticipateCount(request)) {
// 解绑当前线程绑定的EntityManagerHolder
EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
// 关闭EntityManager
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
}
}
// TaskExecutionAutoConfiguration类主要是为了导入spring.task.execution配置和线程池
@EnableConfigurationProperties(TaskExecutionProperties.class)
class TaskExecutionAutoConfiguration {
@ConfigurationProperties("spring.task.execution")
class TaskExecutionProperties {
}
@Lazy
@Bean(name = {APPLICATION_TASK_EXECUTOR_BEAN_NAME, AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME})
@ConditionalOnMissingBean(Executor.class)
public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
return builder.build();
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({LocalContainerEntityManagerFactoryBean.class, EntityManager.class, SessionImplementor.class})
// 导入属性
@EnableConfigurationProperties(JpaProperties.class)
// 在数据源配置好之后加载
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
// 导入HibernateJpa的配置
@Import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {
// 开启jPA配置
@ConfigurationProperties(prefix = "spring.jpa")
class JpaProperties {
}
// 开启spring.jpa.hibernate配置
@EnableConfigurationProperties(HibernateProperties.class)
@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {
@ConfigurationProperties("spring.jpa.hibernate")
class HibernateProperties {
}
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
// 导入数据源配置
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
@ConfigurationProperties(prefix = "spring.datasource")
class DataSourceProperties {
}
@Conditional(EmbeddedDatabaseCondition.class)
@Import(EmbeddedDataSourceConfiguration.class)
protected static class EmbeddedDatabaseConfiguration {
// 开启数据源配置
@EnableConfigurationProperties(DataSourceProperties.class)
class EmbeddedDataSourceConfiguration {
// 配置EmbeddedDatabase数据源
@Bean(destroyMethod = "shutdown")
public EmbeddedDatabase dataSource(DataSourceProperties properties) {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.get(this.classLoader).getType()).setName(properties.determineDatabaseName()).build();
}
}
}
@Conditional(PooledDataSourceCondition.class)
@Import({
// Hikari数据源
DataSourceConfiguration.Hikari.class,
// Tomcat数据源
DataSourceConfiguration.Tomcat.class,
// Dbcp2数据源
DataSourceConfiguration.Dbcp2.class,
// Generic普通数据源
DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
// 属性值为spring.datasource.type=com.zaxxer.hikari.HikariDataSource加载
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
class Hikari {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
HikariDataSource dataSource(DataSourceProperties properties) {
// 创建数据源对象
HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
}
}