LocalContainerEntityManagerFactoryBean源码

news2024/12/26 17:45:51

是 Spring Data JPA 中的一个类,它用于创建 EntityManagerFactory 的实例,获取EntityManager实例

public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean
		implements ResourceLoaderAware, LoadTimeWeaverAware {
		//主要方法
		public void afterPropertiesSet() throws PersistenceException {
		//是一个用于获取JPA持久化单元的接口,主要用于解决多配置文件情况。默认实现是DefaultPersistenceUnitManager
		//用于指定数据源、JPA配置文件、持久化单元名字、持久化实现厂商类以及特定属性等
		PersistenceUnitManager managerToUse = this.persistenceUnitManager;
		if (this.persistenceUnitManager == null) {
			this.internalPersistenceUnitManager.afterPropertiesSet();
			managerToUse = this.internalPersistenceUnitManager;
		}
		//它由容器实现并用于创建 EntityManagerFactory。这个接口提供了关于持久化单元的信息,包括数据源、JPA 配置文件、持久化单元名称、持久化实现厂商类以及特定属性等
		//通过 PersistenceUnitInfo,容器可以向 JPA 提供商提供有关持久化单元的详细信息,以便后者能够根据这些信息创建适当的 EntityManagerFactory。这对于应用程序的持久化逻辑至关重要,因为它决定了如何将数据映射到数据库以及如何执行各种持久化操作
		this.persistenceUnitInfo = determinePersistenceUnitInfo(managerToUse);
		JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
		if (jpaVendorAdapter != null && this.persistenceUnitInfo instanceof SmartPersistenceUnitInfo) {
			String rootPackage = jpaVendorAdapter.getPersistenceProviderRootPackage();
			if (rootPackage != null) {
				((SmartPersistenceUnitInfo) this.persistenceUnitInfo).setPersistenceProviderPackageName(rootPackage);
			}
		}

		super.afterPropertiesSet();
	}
}
//创建Native EntityManangerFactory
protected EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException {
		Assert.state(this.persistenceUnitInfo != null, "PersistenceUnitInfo not initialized");

		PersistenceProvider provider = getPersistenceProvider();
		if (provider == null) {
			String providerClassName = this.persistenceUnitInfo.getPersistenceProviderClassName();
			if (providerClassName == null) {
				throw new IllegalArgumentException(
						"No PersistenceProvider specified in EntityManagerFactory configuration, " +
						"and chosen PersistenceUnitInfo does not specify a provider class name either");
			}
			Class<?> providerClass = ClassUtils.resolveClassName(providerClassName, getBeanClassLoader());
			provider = (PersistenceProvider) BeanUtils.instantiateClass(providerClass);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Building JPA container EntityManagerFactory for persistence unit '" +
					this.persistenceUnitInfo.getPersistenceUnitName() + "'");
		}
		EntityManagerFactory emf =
				provider.createContainerEntityManagerFactory(this.persistenceUnitInfo, getJpaPropertyMap());
		postProcessEntityManagerFactory(emf, this.persistenceUnitInfo);

		return emf;
	}

AbstractEntityManagerFactoryBean

public void afterPropertiesSet() throws PersistenceException {
		//JpaVendorAdapter是一个接口,用于设置实现厂商JPA实现的特定属性
		JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
		if (jpaVendorAdapter != null) {
			if (this.persistenceProvider == null) {
				this.persistenceProvider = jpaVendorAdapter.getPersistenceProvider();
			}
			PersistenceUnitInfo pui = getPersistenceUnitInfo();
			Map<String, ?> vendorPropertyMap = (pui != null ? jpaVendorAdapter.getJpaPropertyMap(pui) :
					jpaVendorAdapter.getJpaPropertyMap());
			if (!CollectionUtils.isEmpty(vendorPropertyMap)) {
				vendorPropertyMap.forEach((key, value) -> {
					if (!this.jpaPropertyMap.containsKey(key)) {
						this.jpaPropertyMap.put(key, value);
					}
				});
			}
			if (this.entityManagerFactoryInterface == null) {
				this.entityManagerFactoryInterface = jpaVendorAdapter.getEntityManagerFactoryInterface();
				if (!ClassUtils.isVisible(this.entityManagerFactoryInterface, this.beanClassLoader)) {
					this.entityManagerFactoryInterface = EntityManagerFactory.class;
				}
			}
			if (this.entityManagerInterface == null) {
				this.entityManagerInterface = jpaVendorAdapter.getEntityManagerInterface();
				if (!ClassUtils.isVisible(this.entityManagerInterface, this.beanClassLoader)) {
					this.entityManagerInterface = EntityManager.class;
				}
			}
			if (this.jpaDialect == null) {
				this.jpaDialect = jpaVendorAdapter.getJpaDialect();
			}
		}
		//构建EntityManagerFactory
		//创建一个本地的EntityManagerFactory
		AsyncTaskExecutor bootstrapExecutor = getBootstrapExecutor();
		if (bootstrapExecutor != null) {
			this.nativeEntityManagerFactoryFuture = bootstrapExecutor.submit(this::buildNativeEntityManagerFactory);
		}
		else {
			this.nativeEntityManagerFactory = buildNativeEntityManagerFactory();
		}
		//然后创建真正使用的EntityManagerFactory
		this.entityManagerFactory = createEntityManagerFactoryProxy(this.nativeEntityManagerFactory);
	}
//这个才是我们真正需要的EntityManagerFactory
protected EntityManagerFactory createEntityManagerFactoryProxy(@Nullable EntityManagerFactory emf) {
		Set<Class<?>> ifcs = new LinkedHashSet<>();
		Class<?> entityManagerFactoryInterface = this.entityManagerFactoryInterface;
		if (entityManagerFactoryInterface != null) {
			ifcs.add(entityManagerFactoryInterface);
		}
		else if (emf != null) {
			ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(emf.getClass(), this.beanClassLoader));
		}
		else {
			ifcs.add(EntityManagerFactory.class);
		}
		ifcs.add(EntityManagerFactoryInfo.class);

		try {
			return (EntityManagerFactory) Proxy.newProxyInstance(this.beanClassLoader,
					ClassUtils.toClassArray(ifcs), new ManagedEntityManagerFactoryInvocationHandler(this));
		}
		catch (IllegalArgumentException ex) {
			if (entityManagerFactoryInterface != null) {
				throw new IllegalStateException("EntityManagerFactory interface [" + entityManagerFactoryInterface +
						"] seems to conflict with Spring's EntityManagerFactoryInfo mixin - consider resetting the "+
						"'entityManagerFactoryInterface' property to plain [javax.persistence.EntityManagerFactory]", ex);
			}
			else {
				throw new IllegalStateException("Conflicting EntityManagerFactory interfaces - " +
						"consider specifying the 'jpaVendorAdapter' or 'entityManagerFactoryInterface' property " +
						"to select a specific EntityManagerFactory interface to proceed with", ex);
			}
		}
	}
Object invokeProxyMethod(Method method, @Nullable Object[] args) throws Throwable {
		if (method.getDeclaringClass().isAssignableFrom(EntityManagerFactoryInfo.class)) {
			return method.invoke(this, args);
		}
		else if (method.getName().equals("createEntityManager") && args != null && args.length > 0 &&
				args[0] == SynchronizationType.SYNCHRONIZED) {
			// JPA 2.1's createEntityManager(SynchronizationType, Map)
			// Redirect to plain createEntityManager and add synchronization semantics through Spring proxy
			EntityManager rawEntityManager = (args.length > 1 ?
					getNativeEntityManagerFactory().createEntityManager((Map<?, ?>) args[1]) :
					getNativeEntityManagerFactory().createEntityManager());
			postProcessEntityManager(rawEntityManager);
			return ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, true);
		}

		// Look for Query arguments, primarily JPA 2.1's addNamedQuery(String, Query)
		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				Object arg = args[i];
				if (arg instanceof Query && Proxy.isProxyClass(arg.getClass())) {
					// Assumably a Spring-generated proxy from SharedEntityManagerCreator:
					// since we're passing it back to the native EntityManagerFactory,
					// let's unwrap it to the original Query object from the provider.
					try {
						args[i] = ((Query) arg).unwrap(null);
					}
					catch (RuntimeException ex) {
						// Ignore - simply proceed with given Query object then
					}
				}
			}
		}

		// Standard delegation to the native factory, just post-processing EntityManager return values
		Object retVal = method.invoke(getNativeEntityManagerFactory(), args);
		if (retVal instanceof EntityManager) {
			// Any other createEntityManager variant - expecting non-synchronized semantics
			EntityManager rawEntityManager = (EntityManager) retVal;
			postProcessEntityManager(rawEntityManager);
			//通过creator创建
			retVal = ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, false);
		}
		return retVal;
	}

ManagedEntityManagerFactoryInvocationHandler

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			switch (method.getName()) {
				case "equals":
					// Only consider equal when proxies are identical.
					return (proxy == args[0]);
				case "hashCode":
					// Use hashCode of EntityManagerFactory proxy.
					return System.identityHashCode(proxy);
				case "unwrap":
					// Handle JPA 2.1 unwrap method - could be a proxy match.
					Class<?> targetClass = (Class<?>) args[0];
					if (targetClass == null) {
						return this.entityManagerFactoryBean.getNativeEntityManagerFactory();
					}
					else if (targetClass.isInstance(proxy)) {
						return proxy;
					}
					break;
			}

			try {
				//真正执行创建的逻辑的方法
				return this.entityManagerFactoryBean.invokeProxyMethod(method, args);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}

ExtendedEntityManagerCreator

public static EntityManager createApplicationManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerFactoryInfo emfInfo, boolean synchronizedWithTransaction) {

		return createProxy(rawEntityManager, emfInfo, false, synchronizedWithTransaction);
}
private static EntityManager createProxy(EntityManager rawEntityManager,
			EntityManagerFactoryInfo emfInfo, boolean containerManaged, boolean synchronizedWithTransaction) {

		Assert.notNull(emfInfo, "EntityManagerFactoryInfo must not be null");
		JpaDialect jpaDialect = emfInfo.getJpaDialect();
		PersistenceUnitInfo pui = emfInfo.getPersistenceUnitInfo();
		Boolean jta = (pui != null ? pui.getTransactionType() == PersistenceUnitTransactionType.JTA : null);
		return createProxy(rawEntityManager, emfInfo.getEntityManagerInterface(),
				emfInfo.getBeanClassLoader(), jpaDialect, jta, containerManaged, synchronizedWithTransaction);
}
private static EntityManager createProxy(
			EntityManager rawEm, @Nullable Class<? extends EntityManager> emIfc, @Nullable ClassLoader cl,
			@Nullable PersistenceExceptionTranslator exceptionTranslator, @Nullable Boolean jta,
			boolean containerManaged, boolean synchronizedWithTransaction) {

		Assert.notNull(rawEm, "EntityManager must not be null");
		Class<?>[] interfaces;

		if (emIfc != null) {
			interfaces = cachedEntityManagerInterfaces.computeIfAbsent(emIfc, key -> {
				Set<Class<?>> ifcs = new LinkedHashSet<>(4);
				ifcs.add(key);
				ifcs.add(EntityManagerProxy.class);
				return ClassUtils.toClassArray(ifcs);
			});
		}
		else {
			interfaces = cachedEntityManagerInterfaces.computeIfAbsent(rawEm.getClass(), key -> {
				Set<Class<?>> ifcs = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(key, cl));
				ifcs.add(EntityManagerProxy.class);
				return ClassUtils.toClassArray(ifcs);
			});
		}

		return (EntityManager) Proxy.newProxyInstance(
				(cl != null ? cl : ExtendedEntityManagerCreator.class.getClassLoader()),
				interfaces,
				new ExtendedEntityManagerInvocationHandler(
						rawEm, exceptionTranslator, jta, }

创建EntityManager流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty源码二:服务端创建NioEventLoopGroup

示例 还是拿之前启动源码的示例&#xff0c;来分析NioEventLoopGroup源码 NioEventLoopGroup构造函数 这里能看到会调到父类的MultiThread EventLoopGroup的构造方法 MultiThreadEventLoopGroup 这里我们能看到&#xff0c;如果传入的线程数目为0&#xff0c;那么就会设置2倍…

RabbitMQ-如何保证消息不丢失

RabbitMQ常用于 异步发送&#xff0c;mysql&#xff0c;redis&#xff0c;es之间的数据同步 &#xff0c;分布式事务&#xff0c;削峰填谷等..... 在微服务中&#xff0c;rabbitmq是我们经常用到的消息中间件。它能够异步的在各个业务之中进行消息的接受和发送&#xff0c;那么…

代码随想录算法刷题训练营day19

代码随想录算法刷题训练营day19&#xff1a;LeetCode(404)左叶子之和、LeetCode(112)路径总和、LeetCode(113)路径总和 II、LeetCode(105)从前序与中序遍历序列构造二叉树、LeetCode(106)从中序与后序遍历序列构造二叉树 LeetCode(404)左叶子之和 题目 代码 /*** Definitio…

GitHub 上传文件夹到远程仓库、再次上传修改文件、如何使用lfs上传大文件、github报错一些问题

按照大家的做法&#xff0c;把自己遇到的问题及解决方案写出来&#xff08;注意&#xff1a;Error里面有些方法有时候我用可以成功&#xff0c;有时候我用也不能成功&#xff0c;写出来仅供参考&#xff0c;实在不行重头再clone&#xff0c;add&#xff0c;commit&#xff0c;p…

Virtual Assistant for Smartphone;Denoising Autoencoder;CrossMAE

本文首发于公众号&#xff1a;机器感知 Virtual Assistant for Smartphone&#xff1b;Denoising Autoencoder&#xff1b;CrossMAE The Case for Co-Designing Model Architectures with Hardware While GPUs are responsible for training the vast majority of state-of-t…

dvwa,xss反射型lowmedium

xss&#xff0c;反射型&#xff0c;low&&medium low发现xss本地搭建实操 medium作为初学者的我第一次接触比较浅的绕过思路 low 发现xss 本关无过滤 <script>alert(/xss/)</script> //或 <script>confirm(/xss/)</script> //或 <script&…

vulnhub靶场之EMPIRE:BREAKOUT

一.环境搭建 1.靶场描述 Description Back to the Top Difficulty: Easy This box was created to be an Easy box, but it can be Medium if you get lost. For hints discord Server ( https://discord.gg/7asvAhCEhe ) 2.靶场地址 https://www.vulnhub.com/entry/empire-…

Canny边缘检测算法(python 实现)

1. 应用高斯滤波来平滑(模糊)图像&#xff0c;目的是去除噪声 2. 计算梯度强度和方向&#xff0c;寻找边缘&#xff0c;即灰度强度变化最强的位置 3应用非最大抑制技术NMS来消除边误检模糊&#xff08;blurred&#xff09;的边界变得清晰&#xff08;sharp&#xff09;。保留了…

力扣题目训练(3)

2024年1月27日力扣题目训练 2024年1月27日力扣题目训练290. 单词规律292. Nim 游戏303. 区域和检索 - 数组不可变91. 解码方法92. 反转链表 II41. 缺失的第一个正数 2024年1月27日力扣题目训练 2024年1月27日第三天编程训练&#xff0c;今天主要是进行一些题训练&#xff0c;包…

机器学习算法实战案例:使用 Transformer 模型进行时间序列预测实战(升级版)

时间序列预测是一个经久不衰的主题&#xff0c;受自然语言处理领域的成功启发&#xff0c;transformer模型也在时间序列预测有了很大的发展。 本文可以作为学习使用Transformer 模型的时间序列预测的一个起点。 文章目录 机器学习算法实战案例系列答疑&技术交流数据集数据…

Java RC4加密算法

一、RC4加密算法 在密码学中&#xff0c;RC4&#xff08;来自Rivest Cipher 4的缩写&#xff09;是一种流加密算法&#xff0c;密钥长度可变。它加解密使用相同的密钥&#xff0c;因此也属于对称加密算法。 百度百科 - RC4&#xff1a;https://baike.baidu.com/item/RC4/34545…

揭秘1688商品详情API接口:一探阿里巴巴的亿级商品数据宝藏

一、概述 1688商品详情API接口是阿里巴巴提供的一套应用程序接口&#xff0c;允许第三方开发者获取1688平台上的商品详情信息。通过使用这个接口&#xff0c;开发者可以获取到商品的详细属性、规格参数、价格等信息&#xff0c;从而进行深度分析和挖掘&#xff0c;进一步优化和…

selenium元素定位---元素点击交互异常解决方法

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;薪资嘎嘎涨 1、异常原因 在编写ui自动化时&#xff0c;执行报错元素无法点击&#xff1a;ElementClickIn…

基础算法之Huffman编码

// Type your code here, or load an example. #include<iostream> #include<string> #include<queue> #include <unordered_map> #include <vector>using namespace std;//树节点结构 struct Node {char ch;int freq;Node *left;Node *right;No…

【数据结构】(一)从绪论到各种线性表

目录 一、绪论Introduction 1、数据结构 2、逻辑结构&#xff08;数据元素之间的相互关系&#xff09; 3、物理结构&#xff08;数据逻辑结构在计算机中的存储形式&#xff09; 4、数据类型&#xff08;一组性质相同的值的集合及定义在此集合上的一些操作的总称&#xff09…

幻兽帕鲁服务器多少钱?2024年Palworld游戏主机费用

幻兽帕鲁服务器多少钱&#xff1f;价格便宜&#xff0c;阿里云4核16G幻兽帕鲁专属服务器32元1个月、66元3个月&#xff0c;4核32G配置113元1个月、339元3个月&#xff1b;腾讯云4核16G14M服务器66元1个月、277元3个月、1584元一年。阿腾云atengyun.com分享阿里云和腾讯云palwor…

Python算法题集_找到字符串中所有字母异位词

本文为Python算法题集之一的代码示例 题目438&#xff1a;找到字符串中所有字母异位词 说明&#xff1a;给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字…

Java基础—面向对象OOP—18三大特性:封装、继承与多态

由于本身理解还不是很到位&#xff0c;所以写的很绕&#xff0c;后续待补充优化 1、封装&#xff08;底层&#xff09;&#xff1a;该露的露&#xff0c;该藏的藏 高内聚&#xff1a;类的内部数据操作细节自己完成&#xff0c;不允许外部干涉低耦合&#xff1a;仅暴露少量的方…

休息日的思考与额外题——链表

文章目录 前言链表知识点 一、 92. 反转链表 II二、21. 合并两个有序链表总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划二刷完卡子哥的刷题计划&#xff0c;加油&#xff01; 二刷决定精刷了&#xff0c;于是参加了卡子哥的刷题班&#xff0c;训练…

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测(matlab)

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测&#xff08;matlab&#xff09; SAO-CNN-BiLSTM-Attention雪消融优化器优化卷积-长短期记忆神经网络结合注意力机制的数据回归预测 Matlab语言。 雪消融优化器( SAO) 是受自然界中雪的升华和融化行为的启发&#xff0c;开发了一种…