Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
2011-10-11 13:18
771 查看
Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
Hibernate版本(hibernate-distribution-3.3.1.GA)
之前的一篇文章 Hibernate3源码分析之SettingsFactory类 只是简单分析一下SettingsFactory类读取Hibernate.cfg.xml 配置文件中property元素,将其赋值给Settings类的实例。hibernate.cfg.xml配置文件中远远不止property元素,还有其它元素,哪么其它元素被解析出来后赋值给了哪些个类的实例呢??? (hibernate.cfg.xml配置文件所对应的dtd文件地址) SessionFactory类为什么只需要一个实例就可以了??? 本文将会尝试解答这些问题
一、加载hibernate.cfg.xml配置文件并解析property元素
对这段代码的解析,之前的文章 Hibernate3源码分析之SettingsFactory类 已经分析过了。对Configruation类进行实例化后,接下来就调用该实例的configure()方法,该方法将会读取hibernate.cfg.xml文件
Configuraiton.java
当调用Configruation类的configure方法将会执行许多函数,其顺序如上所示。最终将目标放在addProperties和parseSessionFactory这两个函数上面。先简单看一下hibernate.cfg.xml文件的格式
hibernate.cfg.xml
HbmBinder类负责解析mapping 元素 每一个hbm.xml文件对应一个Mappings类的实例
[1] addProperties 解析hibernate.cfg.xml配置文件中property元素的,等到调用buildSessionFactory时,将会有SettingsFactory将这些properties赋值给Settings类的实例
[2] parseSessionFactory 解析hibernate.cfg.xml配置文件中除了property元素外的其它元素
二、分析Configruation类的中parseSessionFactory函数
Configuration.java
parseSessionFactory函数的源代码如上所示, 可以看出 hibernate.cfg.xml中根元素session-factory元素下的 mapping class-cache collection-cache listener event 这些元素分别由相对应的函数来处理。parseSessionFactory相当于一个dispatcher。
这里只分析一下 解析hibernate.cfg.xml配置文件中mapping元素parseMappingElement函数
Configuration.java
hibernate.cfg.xml文件最终将会由HbmBinder类来解析完成。哪么mappings元素解析出来,赋值给了谁呢? 答案就在上面代码中的 createMappings()方法里。
实例化一个Mappings类,而传入这些参数正是 Configuraiton中的字段 也就是说Configuration和Mappings是一对多的关系 。搞不清楚为什么在这里只是用Mappings类作为桥梁实例化这些字段,而不添加一个Mappins类的引用。在这里的解答了第一个问题。mapping元素被解析赋值给Configuration类的某些字段,也可以看成是一个hbm.xml文件对应一个mappings类的实例。当执行parseSessionFactory函数之后,就可以调用buildSessionFactory函数来创建SessionFactory了。
SessionFactory实例中存储了一个Settings类的实例和多个Mappings类的实例,数量取决于hbm.xml文件的数量
解答第二个问题:SessionFactory类为什么只需要一个实例就可以了??? Confiuguration 类通过 buildSessionFactory 构造SessionFactory 。SessionFactory是一个会话工厂, 工厂是用来加工、制造和生产的 前提它得有原料和能源。Configuration类读取并解析了hibernate.cfg.xml文件,SessionFactory是由它来构造,它向SessionFactory提供了hibernate.cfg.xml配置文件的信息。当Configuration类加载hibernate.cfg.xml,就算你创建了两个SessionFactory类的实例,它们使用的都是同一个hibernate.cfg.xml配置文件信息,没有必要。除非加载另外一个不同的hibernate.cfg.xml文件。
Hibernate版本(hibernate-distribution-3.3.1.GA)
之前的一篇文章 Hibernate3源码分析之SettingsFactory类 只是简单分析一下SettingsFactory类读取Hibernate.cfg.xml 配置文件中property元素,将其赋值给Settings类的实例。hibernate.cfg.xml配置文件中远远不止property元素,还有其它元素,哪么其它元素被解析出来后赋值给了哪些个类的实例呢??? (hibernate.cfg.xml配置文件所对应的dtd文件地址) SessionFactory类为什么只需要一个实例就可以了??? 本文将会尝试解答这些问题
一、加载hibernate.cfg.xml配置文件并解析property元素
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(); } }
对这段代码的解析,之前的文章 Hibernate3源码分析之SettingsFactory类 已经分析过了。对Configruation类进行实例化后,接下来就调用该实例的configure()方法,该方法将会读取hibernate.cfg.xml文件
Configuraiton.java
public Configuration configure() throws HibernateException { configure( "/hibernate.cfg.xml" ); // [1] return this; } public Configuration configure(String resource) throws HibernateException { log.info( "configuring from resource: " + resource ); InputStream stream = getConfigurationInputStream( resource ); return doConfigure( stream, resource ); //[2] } protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException { org.dom4j.Document doc; //省略 ... return doConfigure( doc ); //[3] } protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException { //省略 ... addProperties( sfNode ); parseSessionFactory( sfNode, name ); //省略 ... return this; }
当调用Configruation类的configure方法将会执行许多函数,其顺序如上所示。最终将目标放在addProperties和parseSessionFactory这两个函数上面。先简单看一下hibernate.cfg.xml文件的格式
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="..."> ... </property> <property name="..."> ... </property> <mapping resource="..." /> <mapping resource="..." /> </session-factory> </hibernate-configuration>
HbmBinder类负责解析mapping 元素 每一个hbm.xml文件对应一个Mappings类的实例
[1] addProperties 解析hibernate.cfg.xml配置文件中property元素的,等到调用buildSessionFactory时,将会有SettingsFactory将这些properties赋值给Settings类的实例
[2] parseSessionFactory 解析hibernate.cfg.xml配置文件中除了property元素外的其它元素
二、分析Configruation类的中parseSessionFactory函数
Configuration.java
private void parseSessionFactory(Element sfNode, String name) { Iterator elements = sfNode.elementIterator(); while ( elements.hasNext() ) { Element subelement = (Element) elements.next(); String subelementName = subelement.getName(); if ( "mapping".equals( subelementName ) ) { parseMappingElement( subelement, name ); // [a] } else if ( "class-cache".equals( subelementName ) ) { String className = subelement.attributeValue( "class" ); Attribute regionNode = subelement.attribute( "region" ); final String region = ( regionNode == null ) ? className : regionNode.getValue(); boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) ); setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy ); // [b] } else if ( "collection-cache".equals( subelementName ) ) { String role = subelement.attributeValue( "collection" ); Attribute regionNode = subelement.attribute( "region" ); final String region = ( regionNode == null ) ? role : regionNode.getValue(); setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region ); // [c] } else if ( "listener".equals( subelementName ) ) { parseListener( subelement ); // [d] } else if ( "event".equals( subelementName ) ) { parseEvent( subelement ); // [e] } } }
parseSessionFactory函数的源代码如上所示, 可以看出 hibernate.cfg.xml中根元素session-factory元素下的 mapping class-cache collection-cache listener event 这些元素分别由相对应的函数来处理。parseSessionFactory相当于一个dispatcher。
这里只分析一下 解析hibernate.cfg.xml配置文件中mapping元素parseMappingElement函数
Configuration.java
protected void parseMappingElement(Element subelement, String name) { Attribute rsrc = subelement.attribute( "resource" ); Attribute file = subelement.attribute( "file" ); Attribute jar = subelement.attribute( "jar" ); Attribute pkg = subelement.attribute( "package" ); Attribute clazz = subelement.attribute( "class" ); //省略 ... addFile( file.getValue() ); // [1] } } public Configuration addFile(String xmlFile) throws MappingException { return addFile( new File( xmlFile ) ); // [2] } public Configuration addFile(File xmlFile) throws MappingException { // 省略 ... try { //省略 ... add( doc ); // [3] return this; } //省略 ... } protected void add(org.dom4j.Document doc) throws MappingException { HbmBinder.bindRoot( doc, createMappings(), CollectionHelper.EMPTY_MAP ); //[4] }
hibernate.cfg.xml文件最终将会由HbmBinder类来解析完成。哪么mappings元素解析出来,赋值给了谁呢? 答案就在上面代码中的 createMappings()方法里。
public Mappings createMappings() { return new Mappings( classes, collections, tables, namedQueries, namedSqlQueries, sqlResultSetMappings, imports, secondPasses, propertyReferences, namingStrategy, typeDefs, filterDefinitions, extendsQueue, auxiliaryDatabaseObjects, tableNameBinding, columnNameBindingPerTable ); }
实例化一个Mappings类,而传入这些参数正是 Configuraiton中的字段 也就是说Configuration和Mappings是一对多的关系 。搞不清楚为什么在这里只是用Mappings类作为桥梁实例化这些字段,而不添加一个Mappins类的引用。在这里的解答了第一个问题。mapping元素被解析赋值给Configuration类的某些字段,也可以看成是一个hbm.xml文件对应一个mappings类的实例。当执行parseSessionFactory函数之后,就可以调用buildSessionFactory函数来创建SessionFactory了。
SessionFactory实例中存储了一个Settings类的实例和多个Mappings类的实例,数量取决于hbm.xml文件的数量
解答第二个问题:SessionFactory类为什么只需要一个实例就可以了??? Confiuguration 类通过 buildSessionFactory 构造SessionFactory 。SessionFactory是一个会话工厂, 工厂是用来加工、制造和生产的 前提它得有原料和能源。Configuration类读取并解析了hibernate.cfg.xml文件,SessionFactory是由它来构造,它向SessionFactory提供了hibernate.cfg.xml配置文件的信息。当Configuration类加载hibernate.cfg.xml,就算你创建了两个SessionFactory类的实例,它们使用的都是同一个hibernate.cfg.xml配置文件信息,没有必要。除非加载另外一个不同的hibernate.cfg.xml文件。
相关文章推荐
- Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
- hibernate.cfg.xml配置文件分析
- hibernate.cfg.xml配置文件分析
- hibernate.cfg.xml配置文件分析
- Hibernate配置文件:hibernate.cfg.xml常用属性说明
- Hibernate.cfg.xml配置文件
- hibernate.cfg.xml配置文件防止中文乱码
- hibernate.cfg.xml配置文件对关联关系的书写技巧!
- hibernate.cfg.xml配置文件详解
- Hibernate3.5.4---java application的xml和annotation环境搭建(hibernate.cfg.xml配置文件说明,映射文件Student.hbm.xml说明
- 使用Xdoclet生成Hibernate配置文件(hibernate.cfg.xml)和Hibernate映射文件(*.hbm.xml)
- hibernate.cfg.xml配置文件详解
- Heritrix源码分析(三) 修改配置文件order.xml加快你的抓取速度
- 5.1 Hibernate配置文件(hibernate.cfg.xml)
- Hibernate的主配置文件hibernate.cfg.xml
- Heritrix1.14源码分析(3) 修改配置文件order.xml加快你的抓取速度
- Hibernate的配置文件 Hibernate.cfg.xml与xxx.hbm.xml
- hibernate.cfg.xml文件的配置模板和不同数据库的配置参数
- Hibernate --- hibernate.cfg.xml核心配置文件详解
- hibernate学习(一)hibernate.cfg.xml文件连接mySql、Oracle、SqlServer配置