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配置文件中有关配置项的理解

  

posted @ 2011-09-30 20:25  来自非洲大草原的食人虎  阅读(5142)  评论(4编辑  收藏  举报