Hibernate3 : org.hibernate.cfg.Configuration解析

Hibernate3 : org.hibernate.cfg.Configuration 解析

<o:p> </o:p>

  第一次写文章,不好的地方,请口下留情哈。

  org.hibernate.cfg.Configurations 根据 xml 文件配置整个工作过程中所需要的参数。一般

我们会用 Configuration cfg = new Configuration().configure(); 创建一个配置类。那么,这句话到底做了什么呢?

  首先, new Configuration() 会做些什么呢?我们来看他的源码:

  

  protected Configuration(SettingsFactory settingsFactory) {<o:p></o:p>

        System.out.println("Configuration(SettingsFactory settingsFactory)");<o:p></o:p>

        this.settingsFactory = settingsFactory;<o:p></o:p>

        reset();<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

// 默认构造函数,先 new SettingsFactory() , 然后调用

//protected Configuration(SettingsFactory settingsFactory)

    <o:p> </o:p>

public Configuration() {<o:p></o:p>

        this(new SettingsFactory());<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

reset() 初始化了很多变量,感兴趣的可以去看源代码,没有什么特别的地方。

 

  接着,调用 configure() 方法!

public Configuration configure() throws HibernateException {<o:p></o:p>

        configure("/hibernate.cfg.xml");<o:p></o:p>

        return this;<o:p></o:p>

}<o:p></o:p>

可以看出,默认使用 hibernate.cfg.xml 文件,如果想用自定义的文件,可以调用

configure(“….xml”) 方法。

public Configuration configure(String resource) throws HibernateException {<o:p></o:p>

        log.debug("configuring from resource: " + resource);<o:p></o:p>

        InputStream stream = getConfigurationInputStream(resource);<o:p></o:p>

        return doConfigure(stream, resource);<o:p></o:p>

}<o:p></o:p>

根据 getConfigurationInputStream(resource) 得到文件流, getConfigurationInputStream(resource) 调用 ConfigHelper.getResourceAsStream(resource) <o:p> </o:p>

public static InputStream getResourceAsStream(String resource) {<o:p></o:p>

              String stripped = resource.startsWith("/") ? <o:p></o:p>

                            resource.substring(1) : resource;<o:p></o:p>

              InputStream stream = null; <o:p></o:p>

              ClassLoader classLoader = Thread.currentThread().getContextClassLoader();<o:p></o:p>

              if (classLoader!=null) {<o:p></o:p>

                     stream = classLoader.getResourceAsStream( stripped );<o:p></o:p>

              }

// 这里的代码可能应该是 stream = Environment.class.getResourceAsStream( resource );<o:p></o:p>

              if ( stream == null ) {<o:p></o:p>

                     Environment.class.getResourceAsStream( resource );<o:p></o:p>

              }<o:p></o:p>

<o:p> </o:p>

              if ( stream == null ) {<o:p></o:p>

                     stream = Environment.class.getClassLoader().getResourceAsStream( stripped );<o:p></o:p>

              }<o:p></o:p>

              if ( stream == null ) {<o:p></o:p>

                     throw new HibernateException( resource + " not found" );<o:p></o:p>

              }<o:p></o:p>

              return stream;<o:p></o:p>

       }<o:p></o:p>

然后 doConfigure(stream, resource) <o:p> </o:p>

protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {<o:p></o:p>

org.dom4j.Document doc;<o:p></o:p>

        try {<o:p></o:p>

            List errors = new ArrayList();<o:p></o:p>

            SAXReader saxReader = xmlHelper.createSAXReader(resourceName, errors, entityResolver);<o:p></o:p>

            doc = saxReader.read(new InputSource(stream));<o:p></o:p>

            if (errors.size() != 0) {<o:p></o:p>

                throw new MappingException(<o:p></o:p>

                        "invalid configuration",<o:p></o:p>

                        (Throwable) errors.get(0)<o:p></o:p>

                );<o:p></o:p>

            }<o:p></o:p>

        }<o:p></o:p>

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 ,比较比较。

 

<o:p> </o:p>

在得到 doc 的值

            doc = saxReader.read(new InputSource(stream));<o:p></o:p>

后,调用 protected Configuration doConfigure(org.dom4j.Document doc) ,这个函数主要是根据 doc 的到配置参数,然后存到 properties 中。

  先是设置 session-factory 的名字:

<o:p> </o:p>

Element sfNode = doc.getRootElement().element("session-factory");<o:p></o:p>

        String name = sfNode.attributeValue("name");<o:p></o:p>

        if (name != null) {<o:p></o:p>

             // 保存到 properties 中! <o:p> </o:p>

            properties.setProperty(Environment.SESSION_FACTORY_NAME, name);<o:p></o:p>

        }<o:p></o:p>

<o:p> </o:p>

然后是 addProperties(sfNode) ,把 <property name=" "> </property> 保存到 properties 中。

// 这句话估计又是多余的 <o:p> </o:p>

properties.setProperty(name, value);<o:p></o:p>

<o:p> </o:p>

            if (!name.startsWith("hibernate")) {<o:p></o:p>

                properties.setProperty("hibernate." + name, value);<o:p></o:p>

            }

接着调用了 parseSessionFactory(sfNode, name) ,把 mappingclass-cachecollection-cachelistener 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 文件进行解析。

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

<o:p> </o:p>

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

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值