Hibernate5源码浅析(二)Hibernate中的各种Builder

(近期在研究hibernate5的源码,准备同时写一些随笔分享出来,也方便以后自己查找)

Hibernate5源码浅析(二)Hibernate中的各种Builder

上一篇简单的介绍了hibernate5中一个SessionFactory的创建过程,这里我们把这个过程在深入下去。hibernate的启动过程实际上就是加载配置、解析配置并创建出与当前配置环境匹配对应的Java对象的过程,因此这个过程中肯定会用到大量的创建型设计模式,其中尤其是Builder模式使用最多。例如上一篇中提到的BootstrapServiceRegistryBuilder、MetadataBuilder、sessionFactoryBuilder等。

1. Builder模式

先回头温习一下Builder设计模式,就不容易被hibernate中层层调用的各种XxxBuilder绕晕了。经典Builder模式网上有大量的参考,然而Hibernate中的Builder类与经典模式有些不同(做了一些简化,更加具有实用性),看下面这一段摘自Configuration类中的代码:

    public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {
        log.debug( "Building session factory using provided StandardServiceRegistry" );
        //1.创建MetadataBuilder
        final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder( (StandardServiceRegistry) serviceRegistry );
//2.配置MetadataBuilder
if ( implicitNamingStrategy != null ) { metadataBuilder.applyImplicitNamingStrategy( implicitNamingStrategy ); } if ( physicalNamingStrategy != null ) { metadataBuilder.applyPhysicalNamingStrategy( physicalNamingStrategy ); } if ( sharedCacheMode != null ) { metadataBuilder.applySharedCacheMode( sharedCacheMode ); } if ( !typeContributorRegistrations.isEmpty() ) { for ( TypeContributor typeContributor : typeContributorRegistrations ) { metadataBuilder.applyTypes( typeContributor ); } } if ( !basicTypes.isEmpty() ) { for ( BasicType basicType : basicTypes ) { metadataBuilder.applyBasicType( basicType ); } } if ( sqlFunctions != null ) { for ( Map.Entry<String, SQLFunction> entry : sqlFunctions.entrySet() ) { metadataBuilder.applySqlFunction( entry.getKey(), entry.getValue() ); } } if ( auxiliaryDatabaseObjectList != null ) { for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : auxiliaryDatabaseObjectList ) { metadataBuilder.applyAuxiliaryDatabaseObject( auxiliaryDatabaseObject ); } } if ( attributeConverterDefinitionsByClass != null ) { for ( AttributeConverterDefinition attributeConverterDefinition : attributeConverterDefinitionsByClass.values() ) { metadataBuilder.applyAttributeConverter( attributeConverterDefinition ); } } //3.使用MetadataBuilder创建Metadata final Metadata metadata = metadataBuilder.build();
//4.创建SessionFactoryBuilder
final SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
//5.配置SessionFactoryBuilder
if ( interceptor != null && interceptor != EmptyInterceptor.INSTANCE ) { sessionFactoryBuilder.applyInterceptor( interceptor ); } if ( getSessionFactoryObserver() != null ) { sessionFactoryBuilder.addSessionFactoryObservers( getSessionFactoryObserver() ); } if ( entityNotFoundDelegate != null ) { sessionFactoryBuilder.applyEntityNotFoundDelegate( entityNotFoundDelegate ); } if ( entityTuplizerFactory != null ) { sessionFactoryBuilder.applyEntityTuplizerFactory( entityTuplizerFactory ); } //6.使用SessionFactoryBuilder创建SessionFactory return sessionFactoryBuilder.build(); }

从第一步到第三步,Hibernate的最终目的是要创建一个Metadata对象,然而要创建一个Metadata对象并不是直接New一个那么简单,因此Hibernate提供了一个MetadataBuilder类来专门负责创建Metadata,从第二步中可以看出MetadataBuilder做了大量的判断和处理后才能走到第三步调用build方法创建Metadata对象。后面第四步到第六步创建SessionFactory对象也是同样的道理。因此阅读源码的时候可以先抓住主要过程,中间大量参数准备的内容可以暂时略过。比如上面这段代码中实际上就是做了两件事创建Metadata和创建SessionFactory。

当我们创建一个对象需要判断大量条件和参数时,与其提供带有大量参数的、各种不同重载方式的构造函数(其中可能有部分必传参数部分可选参数),倒不如为它专门提供一个Builder类来负责处理这些创建逻辑,Hibernate中大量的Builder类大多都是这样产生的。

 2.Hibernate中的Builder

2.1 BootstrapServiceRegistryBuilder

我们在Hibernate中遇到的第一个Builder应该就是BootstrapServiceRegistryBuilder,它负责创建BootstrapServiceRegistry(基础服务注册中心):

    public Configuration() {
        this( new BootstrapServiceRegistryBuilder().build() );
    }

BootstrapServiceRegistry中注册的了固定的三个基础服务ClassLoaderService(类加载器服务)、StrategySelector(决策选择器)、IntegratorService(集成服务),其中StrategySelector又是由对应的StrategySelectorBuilder来创建。

        return new BootstrapServiceRegistryImpl(
                autoCloseRegistry,
                classLoaderService,
                strategySelectorBuilder.buildSelector( classLoaderService ),
                integratorService
        );

 2.2 StandardServiceRegistryBuilder

StandardServiceRegistryBuilder用于创建StandardServiceRegistry(标准服务注册中心),这里将注册Hibernate中需要用到的大量服务,上一篇中我们了解到Configuration类中的configure方法实际上是调用了StandardServiceRegistryBuilder的configure方法:

    public Configuration configure(String resource) throws HibernateException {
        standardServiceRegistryBuilder.configure( resource );
        properties.putAll( standardServiceRegistryBuilder.getSettings() );
        return this;
    }

为什么配置文件是由这个StandardServiceRegistryBuilder来装载呢,实际上这正是Hibernate里面Builder模式的主要作用,Builder在创建对象之前需要先获取对象创建参数,然后执行参数判断逻辑,最终创建出目标对象,而此处StandardServiceRegistryBuilder的参数来源就是hibernate配置文件,因此用它来装载配置文件解析其中的参数然后才能创建目标对象。

 

有了对Hibernate中Builder模式的基本理解,再去阅读原码,就更容易抓住逻辑主线了,而不会被大量的参数准备逻辑带晕了。

 

posted @ 2017-11-16 10:45  kuntaljy  阅读(1337)  评论(1编辑  收藏  举报