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