Hibernate3 : org.hibernate.cfg.Configuration解析

  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_RESOLVEXMLHelper默認是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),把mappingclass-cachecollection-cachelistenerevent等配置保存。到底它保存到哪,我也不全知道,只看了

protected void parseMappingElement(Element subelement, String name),根據配置加載了mapping的文件,最後使用HbmBinder : public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas)保存。bindRoot是對mapping中的xml文件進行解析。

HbmBinderConfiguration都有2000行以上的代碼,在Hibernate中有很重要的地位。Configuration使用.cfg.xml,而HbmBinder則使用了.hbm.xml

 

extractRootAttributes( hmNode, mappings )根據<hibernate-mapping>的配置,把分析的結果存入mapping

相關文章
相關標籤/搜索