Springboot关于JPA的初始化过程

本文详细解析了Springboot中JPA的初始化过程,从HibernateJpaAutoConfiguration开始,探讨了Springboot如何进行JPA配置,包括数据源初始化、Hibernate配置、JPA基础配置等方面。通过理解这些配置,有助于在遇到问题时快速定位并解决。

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


前言:
在使用Springboot的过程中,由于Springboot为我们做了大量的初始化配置工作,所以我们在使用的时候只需要进行少许的配置就能达到我们想要的目的, 但是也正因为如此,对于很多不了解其中原委的同学而言一旦配置有问题或者确实配置而报错,从何处开始排查问题便成为了一个困难,甚至当业务需求要求打破springboot的默认配置的时候时候,我们自定义的配置应该如何进行也会难到一部分同学,例如自定义多个数据源。
本文沿着Springboot的配置梳理其对jpa的配置,以便后期关于jpa的地方出问题时知道从何处开始排查问题。


HibernateJpaAutoConfiguration

提示:几乎所有的Springboot应用的初始化都可以从autoconfigure这个包开始查起。

所以我们先来看下auto包下面的东西:
ORM包
从图中我们找到了HibernateJpaAutoConfiguration. 话不都说,直接上代码:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class, SessionImplementor.class })
@EnableConfigurationProperties(JpaProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
@Import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {

}

说明:
1.当SpringJpa以及JPA规范相应的类存在的情况下才进行自动配置。
2.引入JpaProperties (所以需要jpa的自定义配置就可以看这个类)
3.在数据源初始化完成后再进行配置
4.引入Hibernate实现的配置 HibernateJpaConfiguration(hibernate应该算是JPA事实上的标准实现,当年大佬们制定JPA规范的时候是反过来参考Hibernate的)

其它的都比较简单,这里直接看HibernateJpaConfiguration的实现配置:HibernateJpaConfiguration

HibernateJpaConfiguration

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HibernateProperties.class)
@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {
}

还是先看类的结构,首先是引入HibernateProperties,这个配置是针对Hibernate实现的特殊配置,它与刚才提到的JpaProperties构成了我们整个应用的关于ORM的配置。例如是否显示sql,是否自动DDL。
@ConditionalOnSingleCandidate(DataSource.class) 已经实例化DataSource,并且只有一个可选项。
其次它还继承了JpaBaseConfiguration(JPA的一些基础配置),所以这里除了它自身hibernate的配置之外还有jpa的配置。

还是先看hibernate的实现,上代码:
首先是初始化:

HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
			ConfigurableListableBeanFactory beanFactory, ObjectProvider<JtaTransactionManager> jtaTransactionManager,
			HibernateProperties hibernateProperties,
			ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders,
			ObjectProvider<SchemaManagementProvider> providers,
			ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy,
			ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy,
			ObjectProvider<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
		super(dataSource, jpaProperties, jtaTransactionManager);
		this.hibernateProperties = hibernateProperties;
		this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(providers);
		this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(metadataProviders.getIfAvailable());
		this.hibernatePropertiesCustomizers = determineHibernatePropertiesCustomizers(
				physicalNamingStrategy.getIfAvailable(), implicitNamingStrategy.getIfAvailable(), beanFactory,
				hibernatePropertiesCustomizers.orderedStream().collect(Collectors.toList()));
	}

	private List<HibernatePropertiesCustomizer> determineHibernatePropertiesCustomizers(
			PhysicalNamingStrategy physicalNamingStrategy, ImplicitNamingStrategy implicitNamingStrategy,
			ConfigurableListableBeanFactory beanFactory,
			List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
		List<HibernatePropertiesCustomizer> customizers = new ArrayList<>();
		if (ClassUtils.isPresent("org.hibernate.resource.beans.container.spi.BeanContainer",
				getClass().getClassLoader())) {
			customizers.add((properties) -> properties.put(AvailableSettings.BEAN_CONTAINER,
					new SpringBeanContainer(beanFactory)));
		}
		if (physicalNamingStrategy != null || implicitNamingStrategy != null) {
			customizers.add(
					new NamingStrategiesHibernatePropertiesCustomizer(physicalNamingStrategy, implicitNamingStrategy));
		}
		customizers.addAll(hibernatePropertiesCustomizers);
		return customizers;
	}

这里会初始化HibernateProperties、HibernateDefaultDdlAutoProvider、CompositeDataSourcePoolMetadataProvider、hibernatePropertiesCustomizers;其中hibernatePropertiesCustomizers包括了手动设置的BeanContainer(spring的具体实现,为hibernate提供容器IOC的能力),还有xxxxNamingStrategy,用于将domain对象的注解与数据库字段对应上。

HibernateJpaConfiguration 继承至JpaBaseConfiguration

JpaBaseConfiguration

该类主要初始化Jpa规范中的核心“接口”,包括:TransactionManager、JpaVendorAdapter、LocalContainerEntityManagerFactoryBean(EntityManager),如果开启了openSessionInView(配置文件中配置spring.jpa.open-in-view=true),则还会初始化OpenEntityManagerInViewInterceptor这个拦截器然后配置到Controller的拦截中。

DataSourceInitializedPublisher

这个类从注释可以看出是用于ORM框架自动DDL的,它是在初始化JpaBaseConfiguration的时候@Import进去的,同时它也是一个bean后置处理器。

后续会对事务、实体管理器、openSessionInView、自动DDL等进行一一详细的讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值