VIRGIN FOREST OF JAVA
不要埋头苦干,要学习,学习,再学习。。。。。
powered by R.Zeus

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 阅读(2973) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: