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說開去


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM