org.hibernate.cfg.Configurations根據xml文件配置整個工做過程當中所須要的參數。通常java
咱們會用Configuration cfg = new Configuration().configure();建立一個配置類。那麼,這句話到底作了什麼呢?session
首先,new Configuration()會作些什麼呢?咱們來看他的源碼:app
protected Configuration(SettingsFactory settingsFactory) {dom
System.out.println("Configuration(SettingsFactory settingsFactory)");函數
this.settingsFactory = settingsFactory;this
reset();spa
}.net
//默認構造函數,先new SettingsFactory(),而後調用hibernate
//protected Configuration(SettingsFactory settingsFactory)debug
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。