SpringBoot中整合SpringDataJPA的关键类总结

本文详细解析了SpringBoot中如何通过`spring.factories`文件管理和配置JPA仓库(JpaRepository)、EntityManagerFactory的创建过程,以及如何处理`@OpenEntityManagerInView`注解的自动管理,涉及到条件注解、自动配置和数据源集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 在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;
            }
        }
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值