LocalContainerEntityManagerFactoryBean与LocalSessionFactoryBean

LocalContainerEntityManagerFactoryBean

是 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, }

LocalContainerEntityManagerFactoryBean与LocalSessionFactoryBean_第1张图片

LocalSessionFactoryBean

public class LocalSessionFactoryBean extends HibernateExceptionTranslator
		implements FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean {
		public void afterPropertiesSet() throws IOException {
		LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver);
		//设置hibernate核心配置文件 hibernate-cfg.xml
		if (this.configLocations != null) {
			for (Resource resource : this.configLocations) {
				// Load Hibernate configuration from given location.
				sfb.configure(resource.getURL());
			}
		}
		//设置hibernate的映射文件
		if (this.mappingResources != null) {
			// Register given Hibernate mapping definitions, contained in resource files.
			for (String mapping : this.mappingResources) {
				Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader());
				sfb.addInputStream(mr.getInputStream());
			}
		}
		//设置hibernate的映射文件
		if (this.mappingLocations != null) {
			// Register given Hibernate mapping definitions, contained in resource files.
			for (Resource resource : this.mappingLocations) {
				sfb.addInputStream(resource.getInputStream());
			}
		}
		//设置hibernate的缓存文件
		if (this.cacheableMappingLocations != null) {
			// Register given cacheable Hibernate mapping definitions, read from the file system.
			for (Resource resource : this.cacheableMappingLocations) {
				sfb.addCacheableFile(resource.getFile());
			}
		}
		//设置hibernate的映射文件(jar包中的映射文件)
		if (this.mappingJarLocations != null) {
			// Register given Hibernate mapping definitions, contained in jar files.
			for (Resource resource : this.mappingJarLocations) {
				sfb.addJar(resource.getFile());
			}
		}
		//设置hibernate的映射文件存在的目录路径下的文件
		if (this.mappingDirectoryLocations != null) {
			// Register all Hibernate mapping definitions in the given directories.
			for (Resource resource : this.mappingDirectoryLocations) {
				File file = resource.getFile();
				if (!file.isDirectory()) {
					throw new IllegalArgumentException(
							"Mapping directory location [" + resource + "] does not denote a directory");
				}
				sfb.addDirectory(file);
			}
		}
		//实体拦截器 监听实体更改变化的监听器
		if (this.entityInterceptor != null) {
			sfb.setInterceptor(this.entityInterceptor);
		}
		//namingStrategy  字段映射器 比如命名规则
		if (this.namingStrategy != null) {
			sfb.setNamingStrategy(this.namingStrategy);
		}
		//事务管理器
		if (this.jtaTransactionManager != null) {
			sfb.setJtaTransactionManager(this.jtaTransactionManager);
		}

		if (this.multiTenantConnectionProvider != null) {
			sfb.setMultiTenantConnectionProvider(this.multiTenantConnectionProvider);
		}

		if (this.currentTenantIdentifierResolver != null) {
			sfb.setCurrentTenantIdentifierResolver(this.currentTenantIdentifierResolver);
		}
		//缓存工厂
		if (this.cacheRegionFactory != null) {
			sfb.setCacheRegionFactory(this.cacheRegionFactory);
		}
		//实体类型映射过滤器
		if (this.entityTypeFilters != null) {
			sfb.setEntityTypeFilters(this.entityTypeFilters);
		}
		//其他hibernate属性设置
		if (this.hibernateProperties != null) {
			sfb.addProperties(this.hibernateProperties);
		}
		//hibernate注解
		if (this.annotatedClasses != null) {
			sfb.addAnnotatedClasses(this.annotatedClasses);
		}
		//hibernate 注解所在的包路径
		if (this.annotatedPackages != null) {
			sfb.addPackages(this.annotatedPackages);
		}
		//扫描包路径
		if (this.packagesToScan != null) {
			sfb.scanPackages(this.packagesToScan);
		}

		// Build SessionFactory instance.
		this.configuration = sfb;
		this.sessionFactory = buildSessionFactory(sfb);
	}
}
protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {
		return sfb.buildSessionFactory();
	}

LocalSessionFactoryBuilder

public SessionFactory buildSessionFactory() throws HibernateException {
		ClassLoader appClassLoader = (ClassLoader) getProperties().get(AvailableSettings.APP_CLASSLOADER);
		Thread currentThread = Thread.currentThread();
		ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
		boolean overrideClassLoader =
				(appClassLoader != null && !appClassLoader.equals(threadContextClassLoader));
		if (overrideClassLoader) {
			currentThread.setContextClassLoader(appClassLoader);
		}
		try {
			return super.buildSessionFactory();
		}
		finally {
			if (overrideClassLoader) {
				currentThread.setContextClassLoader(threadContextClassLoader);
			}
		}
	}

Configuration

public SessionFactory buildSessionFactory() throws HibernateException {
		Environment.verifyProperties( properties );
		ConfigurationHelper.resolvePlaceHolders( properties );
		final ServiceRegistry serviceRegistry =  new StandardServiceRegistryBuilder()
				.applySettings( properties )
				.build();
		setSessionFactoryObserver(
				new SessionFactoryObserver() {
					@Override
					public void sessionFactoryCreated(SessionFactory factory) {
					}

					@Override
					public void sessionFactoryClosed(SessionFactory factory) {
						( (StandardServiceRegistryImpl) serviceRegistry ).destroy();
					}
				}
		);
		return buildSessionFactory( serviceRegistry );
	}
public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {
		LOG.debugf( "Preparing to build session factory with filters : %s", filterDefinitions );
		
		buildTypeRegistrations( serviceRegistry );
		secondPassCompile();
		if ( !metadataSourceQueue.isEmpty() ) {
			LOG.incompleteMappingMetadataCacheProcessing();
		}

		validate();

		Environment.verifyProperties( properties );
		Properties copy = new Properties();
		copy.putAll( properties );
		ConfigurationHelper.resolvePlaceHolders( copy );
		Settings settings = buildSettings( copy, serviceRegistry );

		return new SessionFactoryImpl(
				this,
				mapping,
				serviceRegistry,
				settings,
				sessionFactoryObserver
			);
	}

LocalContainerEntityManagerFactoryBean与LocalSessionFactoryBean_第2张图片

总结

LocalContainerEntityManagerFactoryBean支持JPA
LocalSessionFactoryBean不支持JPA

你可能感兴趣的:(SpringBoot,spring)