是 Spring Data JPA 中的一个类,它用于创建 EntityManagerFactory 的实例,获取EntityManager实例
public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBeanimplements 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//创建一个本地的EntityManagerFactoryAsyncTaskExecutor bootstrapExecutor = getBootstrapExecutor();if (bootstrapExecutor != null) {this.nativeEntityManagerFactoryFuture = bootstrapExecutor.submit(this::buildNativeEntityManagerFactory);}else {this.nativeEntityManagerFactory = buildNativeEntityManagerFactory();}//然后创建真正使用的EntityManagerFactorythis.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 proxyEntityManager 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 valuesObject retVal = method.invoke(getNativeEntityManagerFactory(), args);if (retVal instanceof EntityManager) {// Any other createEntityManager variant - expecting non-synchronized semanticsEntityManager 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, }