zoukankan      html  css  js  c++  java
  • Hibernate3源码分析之SettingsFactory类

    Hibernate3源码分析之SettingsFactory类

    Hibernate版本(hibernate-distribution-3.3.1.GA)

    一、hibernate.cfg.xml文件的概述

          使用过Hibernate的朋友对hibernate.cfg.xml这个配置文件一点也不会陌生吧,hibernate.cfg.xml之于Hibernate就相当于web.config之于asp.net,二者是密不可分的。hibernate.cfg.xml包含了一系列的属性配置,当程序运行时 会读取该文件并对其进行解析,解析出来的部分内容将会赋值给Setting类的实例。


    二、通过Configruation类构造SessionFactory类的实例

    package com.laoyangx;
    
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class MainConsole {
    
    	public static void main(String[] args) {
    		
    		Configuration conf=new Configuration();
    		conf.configure();
    		
    		SessionFactory factory=conf.buildSessionFactory();	
    	}
    }
    

    上面的代码演示的是如何通过Configuration类构造SessionFactory类的实例,虽然只有三行代码,但实际上执行的代码远远不止三行。Configuration类位于org.hibernate.cfg包中,当使用无参构造函数实例化Configuration类的同时也会初时化一个SettingsFactory类的实例。

    protected Configuration(SettingsFactory settingsFactory) {
    	this.settingsFactory = settingsFactory;
    	reset();
    }
    
    public Configuration() {
           this( new SettingsFactory() );
    }
    

    对Configruation类进行实例化后,接下来就调用该实例的configure()方法,该方法将会读取hibernate.cfg.xml文件

    public Configuration configure() throws HibernateException {
    	configure( "/hibernate.cfg.xml" );
    	return this;
    }
    

    这个函数还会执行许多的其它函数,其最终将会调用HbmBinder类(位于org.hibernate.cfg包中)中相关函数,对  *.hbm.xml 映射文件进行解析,这不是本文的重点,就此跳过。我们把目光转向conf.buildSessionFactory(); 这个函数的源码如下:

    public SessionFactory buildSessionFactory() throws HibernateException {
             
                    //...省略
    
    		Settings settings = buildSettings( copy );
    
                   //...省略
    	}
    
    public Settings buildSettings(Properties props) throws HibernateException {
    		return settingsFactory.buildSettings( props );
    }
    

    可以看出最终将会使用前面已经提到使用无参构造函数实例化Configuration类时也会对SettingsFactory进行实例化的实例来调用SettingsFactory中的buildSettings方法。props参数可以看作是hibernate.cfg.xml配置文件中的property元素在内存中的载体。

    三、通过SettingsFactory构造Settings实例

    public Settings buildSettings(Properties props) {
       Settings settings = new Settings();
       //...省略
    }
    

    可以看到在SettingsFactory类的buildSettings方法中,对Settings类实例化了一个 settings实例。代码中的省略部分就是对其进行赋值。

    四、对Settings类的实例进行赋值

       1. JDBC and connection settings:

     SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	   Settings settings = new Settings();
                    
                       //...省略     
                    
               //JDBC and connection settings:
               ConnectionProvider connections = createConnectionProvider(props);
    	   settings.setConnectionProvider(connections);
                   
                  //...省略     
                    
    }
    
    protected ConnectionProvider createConnectionProvider(Properties properties) {
    		return ConnectionProviderFactory.newConnectionProvider(properties);
    }
    

    上面这段代码可以看出是使用了工厂模式创建ConnectionProvider(位于org.hibernate.connection包中)的实例,其涉及到hibernate.cfg.xml文件中的 hibernate.connection.provider_class 的配置。涉及到ConnectionProviderFactory中newConnectionProvider详细的执行过程,不是本文的重点,跳过。

       2. SQL Dialect:

     SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
           //...省略
    
          //SQL Dialect:
        Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
        settings.setDialect(dialect);
                
           //...省略
    }   
    
    private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
    		return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
    }
    

    上面代码是初始化所使用的数据库方言。其涉及到hibernate.cfg.xml文件中 hibernate.dialect 的配置。也使用了工厂模式

    创建Dialect实例。继承Dialect的类太多,就不用UML表示了。在线API文档的 url:http://www.renren.it/my/api/Hibernate3.3.1GA/org/hibernate/dialect/Dialect.html 

        3. Transaction Settings

     SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
           //...省略
    
          // Transaction settings:
    		
    	TransactionFactory transactionFactory = createTransactionFactory(properties);
    	  settings.setTransactionFactory(transactionFactory);
    	  settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
                
           //...省略
    }   
    
    protected TransactionFactory createTransactionFactory(Properties properties) {
    		return TransactionFactoryFactory.buildTransactionFactory(properties);
    	}
    	
    protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
    	return  TransactionManagerLookupFactory.getTransactionManagerLookup(properties);		
    }
    

    上面的代码分别创建一个TransactionFactory和TransactionManagerLookup的实例。涉及到hibernate.cfg.xml文件中的两个配置项 hibernate.transaction.factory_class 和 hibernate.transaction.manager_lookup_class

    创建TransactionManagerLookup的实例也是使用工厂模式,但是涉及到类太多,就不用UML图表示,给出在线API文档的url:http://www.renren.it/my/api/Hibernate3.3.1GA/org/hibernate/transaction/TransactionManagerLookup.html

        4. BatcherFactory

    SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
           //...省略
    
         settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
                
           //...省略
    }   
    
    protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
    		String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
    		if (batcherClass==null) {
    			return batchSize==0 ?
    					(BatcherFactory) new NonBatchingBatcherFactory() :
    					(BatcherFactory) new BatchingBatcherFactory();
    		}
    		else {
    			log.info("Batcher factory: " + batcherClass);
    			try {
    			return (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance();
    			}
    			catch (Exception cnfe) {
    	                   throw new HibernateException("could not instantiate BatcherFactory: " + batcherClass, cnfe);
    			}
    		}
    	}
    

    上面的代码是创建BatcherFactory的实例,涉及到hibernate.cfg.xml文件中的 hibernate.jdbc.factory_class 配置

       5. Query parser settings

    SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
           //...省略
    
         //Query parser settings:
          settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
                
           //...省略
    }   
    
    protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
        String className = PropertiesHelper.getString(
        Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory");
        
        log.info("Query translator: " + className);
    
         try {
    	    return (QueryTranslatorFactory) ReflectHelper.classForName(className).newInstance();
         } catch (Exception cnfe) {
              throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
           }
    }
    

    上面的代码是创建QueryTranslatorFactory 的实例 默认值是 org.hibernate.hql.ast.ASTQueryTranslatorFactory,涉及到hibernate.cfg.xml文件中的 hibernate.query.factory_class 配置

        6. RegionFactory

    SettingsFactory.java

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
               //...省略
    
              // The cache provider is needed when we either have second-level cache enabled
             // or query cache enabled.  Note that useSecondLevelCache is enabled by default
             settings.setRegionFactory( createRegionFactory( properties, ( useSecondLevelCache || useQueryCache ) ) );
                
           //...省略
    }   
    
    protected RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
        
          String regionFactoryClassName = PropertiesHelper.getString( Environment.CACHE_REGION_FACTORY, properties, null );
    	        if ( regionFactoryClassName == null && cachingEnabled ) {
    			String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, null );
    			if ( providerClassName != null ) {
    				// legacy behavior, apply the bridge...
    				regionFactoryClassName = RegionFactoryCacheProviderBridge.class.getName();
    			}
    		}
    		if ( regionFactoryClassName == null ) {
    			regionFactoryClassName = DEF_CACHE_REG_FACTORY;
    		}
    		log.info( "Cache region factory : " + regionFactoryClassName );
    		try {
    			return ( RegionFactory ) ReflectHelper.classForName( regionFactoryClassName )
    					.getConstructor( new Class[] { Properties.class } )
    					.newInstance( new Object[] { properties } );
    		}
    		catch ( Exception e ) {
    			throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
    		}
    	}
    

    上面的代码是创建 RegionFactory 的实例 其默认值是 NoCachingRegionFactory 涉及到hibernate.cfg.xml文件中的 hibernate.cache.region.factory_class  配置和hibernate.cache.provider_class

       7. QueryCacheFactory

    public Settings buildSettings(Properties props) {
    	Settings settings = new Settings();
            
               //...省略
    
           settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
                
           //...省略
    }   
    
    protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
    		String queryCacheFactoryClassName = PropertiesHelper.getString(
    		Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory");
    		log.info("Query cache factory: " + queryCacheFactoryClassName);
    		try {
    			return (QueryCacheFactory) ReflectHelper.classForName(queryCacheFactoryClassName).newInstance();
    		}
    		catch (Exception cnfe) {
    		throw new HibernateException("could not instantiate QueryCacheFactory: " + queryCacheFactoryClassName, cnfe);
    		}
    }
    

    上面的代码是创建 QueryCacheFactory的实例 其默认值是 org.hibernate.cache.StandardQueryCacheFactory 涉及到hibernate.cfg.xml文件中的 hibernate.cache.query_cache_factory 配置

    简单分析了下SettingsFactory类该类作用就是将hibernate.cfg.xml文件中的部分内容赋值给其实例化的Settings类 。通过阅读该类的源码,对设计模式的中工厂模式有了非常清楚的认识加深了对hibernate.cfg.xml配置文件中有关配置项的理解

      

  • 相关阅读:
    cocospods 卡在 Analyzing dependencies
    android px、sp、dp之间的互转
    Android 4.4环境搭建——Android SDK下载与安装
    我心中的核心组件(可插拔的AOP)~大话开篇及目录
    EF架构~AutoMapper对象映射工具简化了实体赋值的过程
    我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器
    EF架构~为EF DbContext生成的实体添加注释(T5模板应用)
    品味编程~底层开发人员应该这样设计一个字体类
    Study notes for Clustering and K-means
    深入理解Oracle索引(25):一招鲜、吃遍天之单字段索引创建思路
  • 原文地址:https://www.cnblogs.com/yql1986/p/2196621.html
Copyright © 2011-2022 走看看