Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
来源:互联网 发布:福州上海心迹网络骗局 编辑:程序博客网 时间:2024/05/16 11:01
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元素
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
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
5 <hibernate-configuration>
6 <session-factory>
7 <property name="..."> ... </property>
8 <property name="..."> ... </property>
9 <mapping resource="..." />
10 <mapping resource="..." />
11 </session-factory>
12 </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类
- Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
- hibernate.cfg.xml配置文件分析
- hibernate.cfg.xml配置文件分析
- hibernate.cfg.xml配置文件分析
- hibernate3 学习笔记(二) hibernate 的配置文件 hibernate.cfg.xml
- hibernate 配置文件之hibernate.cfg.xml说明
- hibernate 配置文件之hibernate.cfg.xml说明
- Hibernate配置文件之hibernate.cfg.xml
- Hibernate学习之配置文件hibernate.cfg.xml
- hibernate.cfg.xml 配置文件
- hibernate.cfg.xml配置文件
- hibernate.cfg.xml配置文件
- hibernate.cfg.xml配置文件
- Hibernate.cfg.xml配置文件
- Hibernate.cfg.xml配置文件
- hibernate.cfg.xml配置文件
- hibernate.cfg.xml 配置文件
- 使用XStream注解实现Java对象与XML互相转换的代码示例---转自:http://www.blogjava.net/bolo
- ul代替table
- [Hadoop] MapReduce架构设计
- MTK6577+Android启动----pre-loader
- 交通问题
- Hibernate3源码分析之hibernate.cfg.xml配置文件与SessionFactory类
- 详谈MongoDB数据库语法上的五大缺陷
- CIO需加强对战略管理层面的掌控-精华篇
- Hibernate3源码分析之SettingsFactory类
- UIButton使用详解
- 编程算法 - 萨鲁曼的军队(Saruman's Army) 代码(C)
- hdu 2031
- 黑马程序员-04.C语言的函数
- 初探领域驱动设计(1)为复杂业务而生