Spring JPA实现逻辑源码分析总结

 

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。

参考:

Spring JPA实现逻辑源码分析总结

从EnableJpaRepository说开去

原文地址:https://www.cnblogs.com/yuyutianxia/p/7592719.html