Hibernate3 : org.hibernate.cfg.Configuration
解析
?
?
第一次寫文章,不好的地方,請口下留情哈。
?
org.hibernate.cfg.Configurations
根據
xml
文件配置整個工作過程中所需要的參數。一般
我們會用
Configuration cfg = new Configuration().configure();
創建一個配置類。那么,這句話到底做了什么呢?
?
首先,
new Configuration()
會做些什么呢?我們來看他的源碼:
??
?
protected Configuration(SettingsFactory settingsFactory) {
??????? System.out.println("Configuration(SettingsFactory settingsFactory)");
??????? this.settingsFactory = settingsFactory;
??????? reset();
??? }
?
//
默認構造函數,先
new SettingsFactory()
,
然后調用
//protected Configuration(SettingsFactory settingsFactory)
???
public Configuration() {
??????? this(new SettingsFactory());
}
?
reset()
初始化了很多變量,感興趣的可以去看源代碼,沒有什么特別的地方。
?
?
接著,調用
configure()
方法!
public Configuration configure() throws HibernateException {
??????? configure("/hibernate.cfg.xml");
??????? return this;
}
可以看出,默認使用
hibernate.cfg.xml
文件,如果想用自定義的文件,可以調用
configure(“….xml”)
方法。
public Configuration configure(String resource) throws HibernateException {
??????? log.debug("configuring from resource: " + resource);
??????? InputStream stream = getConfigurationInputStream(resource);
??????? return doConfigure(stream, resource);
}
根據
getConfigurationInputStream(resource)
得到文件流,
getConfigurationInputStream(resource)
調用
ConfigHelper.getResourceAsStream(resource)
。
public static InputStream getResourceAsStream(String resource) {
????????????? String stripped = resource.startsWith("/") ?
??????????????????????????? resource.substring(1) : resource;
????????????? InputStream stream = null;
????????????? ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
????????????? if (classLoader!=null) {
???????????????????? stream = classLoader.getResourceAsStream( stripped );
????????????? }
//
這里的代碼可能應該是
stream = Environment.class.getResourceAsStream( resource );
?????????????
if ( stream == null ) {
???????????????????? Environment.class.getResourceAsStream( resource );
????????????? }
?
????????????? if ( stream == null ) {
???????????????????? stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
????????????? }
????????????? if ( stream == null ) {
???????????????????? throw new HibernateException( resource + " not found" );
????????????? }
????????????? return stream;
?????? }
然后
doConfigure(stream, resource)
。
protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
org.dom4j.Document doc;
??????? try {
??????????? List errors = new ArrayList();
??????????? SAXReader saxReader = xmlHelper.createSAXReader(resourceName, errors, entityResolver);
??????????? doc = saxReader.read(new InputSource(stream));
??????????? if (errors.size() != 0) {
??????????????? throw new MappingException(
??????????????????????? "invalid configuration",
??????????????????????? (Throwable) errors.get(0)
??????????????? );
??????????? }
??????? }
entityResolver
在初始值為
entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER
;
在
reset()
的時候設置的。
XMLHelper.DEFAULT_DTD_RESOLVE
在
XMLHelper
默認是
XMLHelper.DEFAULT_DTD_RESOLVER= new DTDEntityResolver()
;
DTDEntityResolver
是用來加載
dtd
文件的。別跟我說你不知道
dtd
是什么東西?它有
3
種加載方式:
1.?
文件路徑以
http://hibernate.sourceforge.net/
開頭的文件,如
http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd
,
它會把
http://hibernate.sourceforge.net
去掉,加上
org/hibernate/
,文件路徑為
org/hibernate/hibernate-configuration-3.0.dtd
,然后加載這個文件。
2.??????
文件路徑以
file://
開頭的文件,如
?
file://hibernate-configuration-3.0.dtd
,
它會把
file://
去掉,路徑為
hibernate-configuration-3.0.dtd
,然后加載這個文件。
3.
如果沒有以上
2
種情況,則直接加載。就是路徑名沒有修改過。
整個過程在
public InputSource resolveEntity(String publicId, String systemId)
中實現。
systemId
就是
dtd
的路徑。大家可以去看看
SAXReader
類自帶的
protected static class SAXEntityResolver
,比較比較。
?
?
在得到
doc
的值
???????????
doc = saxReader.read(new InputSource(stream));
后,調用
protected Configuration doConfigure(org.dom4j.Document doc)
,這個函數主要是根據
doc
的到配置參數,然后存到
properties
中。
?
先是設置
session-factory
的名字:
?
Element sfNode = doc.getRootElement().element("session-factory");
??????? String name = sfNode.attributeValue("name");
??????? if (name != null) {
???????????? //
保存到
properties
中!
??????????? properties.setProperty(Environment.SESSION_FACTORY_NAME, name);
??????? }
?
然后是
addProperties(sfNode)
,把
<property name=" "> </property>
保存到
properties
中。
//
這句話估計又是多余的
properties.setProperty(name, value);
?
??????????
?if (!name.startsWith("hibernate")) {
??????????????? properties.setProperty("hibernate." + name, value);
??????????? }
接著調用了
parseSessionFactory(sfNode, name)
,把
mapping
,
class-cache
,
collection-cache
,
listener
,
event
等配置保存。到底它保存到哪,我也不全知道,只看了
protected void parseMappingElement(Element subelement, String name),
根據配置加載了
mapping
的文件,最后使用
HbmBinder : public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas)
保存。
bindRoot
是對
mapping
中的
xml
文件進行解析。
HbmBinder
和
Configuration
都有
2000
行以上的代碼,在
Hibernate
中有很重要的地位。
Configuration
使用
.cfg.xml
,而
HbmBinder
則使用了
.hbm.xml
。
?
????????????? extractRootAttributes( hmNode, mappings )
根據
<hibernate-mapping>
的配置,把分析的結果存入
mapping
。
?
?
?
?
?
?
?
posted on 2006-08-21 21:12
R.Zeus 閱讀(2990)
評論(0) 編輯 收藏