1、SharedEntityManagerCreator: entitymanager的创建入口
该类被EntityManagerBeanDefinitionRegistrarPostProcessor注册到beanfactory中,依赖EntityManager bean实例的,
都会调用该类的工厂方法createSharedEntityManager,而该工厂方法的参数是EntityManagerFactory,通过BeanDefinitionUtils
找到类型为“EntityManagerFactory.class, AbstractEntityManagerFactoryBean.class”的所有BeanDefinition,针对找到的每个
BeanDefinition,注册一个EntityManager的BeanDefinition
public class EntityManagerBeanDefinitionRegistrarPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { for (EntityManagerFactoryBeanDefinition definition : getEntityManagerFactoryBeanDefinitions(beanFactory)) { if (!(definition.getBeanFactory() instanceof BeanDefinitionRegistry)) { continue; } BeanDefinitionBuilder builder = BeanDefinitionBuilder .rootBeanDefinition("org.springframework.orm.jpa.SharedEntityManagerCreator"); builder.setFactoryMethod("createSharedEntityManager"); builder.addConstructorArgReference(definition.getBeanName()); AbstractBeanDefinition emBeanDefinition = builder.getRawBeanDefinition(); emBeanDefinition.addQualifier(new AutowireCandidateQualifier(Qualifier.class, definition.getBeanName())); emBeanDefinition.setScope(definition.getBeanDefinition().getScope()); emBeanDefinition.setSource(definition.getBeanDefinition().getSource()); BeanDefinitionReaderUtils.registerWithGeneratedName(emBeanDefinition, (BeanDefinitionRegistry) definition.getBeanFactory()); } } }
2、JpaMetamodelMappingContextFactoryBean用来生成JpaMetamodelMappingContext
该FactoryBean创建实例时,遍历所有的EntityManagerFactory,调用EntityManagerFactory.getMetamodel,
将所有的Metamodel加入到一个集合,然后传入JpaMetamodelMappingContext,在将来创建Entity时使用。
class JpaMetamodelMappingContextFactoryBean extends AbstractFactoryBean<JpaMetamodelMappingContext> implements ApplicationContextAware { private ListableBeanFactory beanFactory; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.beanFactory = applicationContext; } @Override public Class<?> getObjectType() { return JpaMetamodelMappingContext.class; } @Override protected JpaMetamodelMappingContext createInstance() throws Exception { Set<Metamodel> models = getMetamodels(); Set<Class<?>> entitySources = new HashSet<Class<?>>(); for (Metamodel metamodel : models) { for (ManagedType<?> type : metamodel.getManagedTypes()) { Class<?> javaType = type.getJavaType(); if (javaType != null) { entitySources.add(javaType); } } } JpaMetamodelMappingContext context = new JpaMetamodelMappingContext(models); context.setInitialEntitySet(entitySources); context.initialize(); return context; } private Set<Metamodel> getMetamodels() { Collection<EntityManagerFactory> factories = BeanFactoryUtils.beansOfTypeIncludingAncestors(beanFactory, EntityManagerFactory.class).values(); Set<Metamodel> metamodels = new HashSet<Metamodel>(factories.size()); for (EntityManagerFactory emf : factories) { metamodels.add(emf.getMetamodel()); } return metamodels; } }
3、JpaRepository中的EntityManager的注入也是通过SharedEntityManagerCreator的工厂方法创建的。
参见JpaRepositoryConfigExtension.getEntityManagerBeanDefinitionFor
4、PersistenceAnnotationBeanPostProcessor: 用来处理persistencecontext,persistenceunit两个注解
直接调用SharedEntityManagerCreator的createSharedEntityManager方法用来注入EntityManager,
位于PersistenceAnnotationBeanPostProcessor$PersistenceElement类内。
5、JpaRepositoryFactoryBean: 创建JpaRepository的工厂类, 实际委托给JpaRepositoryFactory类执行
在创建JpaRepositoryFactory时,通过加入TransactionalRepositoryProxyPostProcessor,在创建JpaRepository过程中
加入TransactionInterceptor,执行JpaRepository方法时,会自动加入事务处理。TransactionInterceptor中会注入配置的
TransactionManager(比如JpaTransactionManager)
6、EntityManager不是线程安全的,EntityManagerFactory是线程安全的
所以需要每次都在线程中生成新的EntityManager。因为注入到容器的EntityManager是个Proxy,所有的调用会委托给
SharedEntityManagerInvocationHandler去处理,间接的实现了线程安全。
7、TransactionSynchronizationManager: 使用ThreadLocal保存事务资源
8、直接通过注入EntityManger执行查询或者保存操作的,由于注入的EntityManager是SharedEntityManagerInvocationHandler的Proxy,
会通过EntityManagerFactoryUtils.doGetTransactionalEntityManager获取已经存在的事务的EntityManager,如果不存在,则会创建一个
EntityManager(有疑问),等调用结束,关闭该EntityManager。
参考: