Hibernate源码解析---------hibernate.cfg.xml读取流程

来源:互联网 发布:新网互联域名证书查询 编辑:程序博客网 时间:2024/05/21 17:29
通常我们使用Hibernate的时候 ,首先要通过以下的代码去创建一个Session.

Java代码  收藏代码
  1. Configuration con=new Configuration().configure();  
  2. ServiceRegistry sr=new ServiceRegistryBuilder().applySettings(con.getProperties()).buildServiceRegistry();  
  3.        
  4.      SessionFactory factory=con.buildSessionFactory(sr);  
  5.        
  6.      Session session=factory.openSession();  
  7.       
  8.      Transaction ts=session.beginTransaction();  





这里先从我们创建sessionfactory的代码入手, 一级级往里看。

Configuration con=new Configuration().configure();

Configuration位于包org.hibernate.cfg下。该类是读取hibernate.cfg.xml文件的入口。
进入该类, 我们看到 1965行,
Java代码  收藏代码
  1. public Configuration configure() throws HibernateException {  
  2.     configure( "/hibernate.cfg.xml" );  
  3.     return this;  
  4. }  

也就是说,在没有放入参数的情况下, hibernate默认会找到名字为hibernate.cfg.xml文件来进行解析。
继续往下看, 找到带参数的configure()。

Java代码  收藏代码
  1. public Configuration configure(String resource) throws HibernateException {  
  2.         LOG.configuringFromResource( resource );  
  3.         InputStream stream = getConfigurationInputStream( resource );  
  4.         return doConfigure( stream, resource );  
  5.     }  


不看LOG, 这里有两个方法被执行。
1. InputStream stream = getConfigurationInputStream(resource);
2003行:
Java代码  收藏代码
  1. protected InputStream getConfigurationInputStream(String resource) throws HibernateException {  
  2.         LOG.configurationResource( resource );  
  3.         return ConfigHelper.getResourceAsStream( resource );  
  4.     }  

继续看ConfigHelper.getResourceAsStream(resource);
ConfigHelper位于org.hibernate.internal.util。
Java代码  收藏代码
  1. public static InputStream getResourceAsStream(String resource) {  
  2.     String stripped = resource.startsWith("/") ?  
  3.             resource.substring(1) : resource;  
  4.   
  5.     InputStream stream = null;  
  6.     ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();  
  7.     if (classLoader!=null) {  
  8.         stream = classLoader.getResourceAsStream( stripped );  
  9.     }  
  10.     if ( stream == null ) {  
  11.         stream = Environment.class.getResourceAsStream( resource );  
  12.     }  
  13.     if ( stream == null ) {  
  14.         stream = Environment.class.getClassLoader().getResourceAsStream( stripped );  
  15.     }  
  16.     if ( stream == null ) {  
  17.         throw new HibernateException( resource + " not found" );  
  18.     }  
  19.     return stream;  
  20. }  


这里也就获取了该xml文件的stream。支线1到此结束。

2.  doConfigure( stream, resource );
Configuration的2064行

Java代码  收藏代码
  1. protected Configuration doConfiguration(InputStream stream, String resourcesName) throws HibernateException {  
  2.    try{  
  3.      Document document=xmlHelper.createSAXReader(errorLogger, entityResolver).read(new InputStream(stream));  
  4. /*关于这个xmlHelper是在哪里被创建的, 我花了点时间才看出来原来是构造函数里面被创建的。 Configuration有两个构造函数字:protected Configuration(SettingsFactory settingsFactory) { 
  5.         this.settingsFactory = settingsFactory; 
  6.         reset(); 
  7.     } 
  8.  
  9.     public Configuration() { 
  10.         this( new SettingsFactory() ); 
  11.     } 
  12. 第二个会在创建Configuration对象的时候调用第一个构造函数, 而第一个函数里面的reset()会创建所有内部的属性对象。 也就是每次创建Configuration,这些都会重置, 所以叫reset。这里学习了。 
  13. */  
  14.   doConfigure(document);  
  15.   finally{  
  16.    stream.close();  
  17.   
  18. }  
  19.   return this;  
  20.   
  21. }  
  22. }  
  23.   
  24. }  


这里看一下doConfugration(Document doc)的代码: (2112行)
Java代码  收藏代码
  1. protected Configuration doConfigure(Document doc) throws HibernateException {  
  2. Element sfNode = doc.getRootElement().element("session-factory");  
  3. String name=sfNode.attributeValue("name");  
  4. if(name!=null){  
  5.   properties.setProperty(Environment.SESSION_FACTORY_NAME, name);  
  6. }  
  7. addProperties(sfNode);  
  8. parseSessionFactory(sfNode, name);  
  9. Element secNode=doc.getRootElement().element("security");  
  10. if(secNode!=null){  
  11. parseSecurity(secNode);  
  12. }  
  13.   
  14. return this;  
  15. }  


}
终于看到我们熟悉的东西了。。T_T 
在此, Element sfNode得到了xml文件里面的<session-factory>节点内容, 并在之后的方法被加入对象 --addProperties(sfNode);

Java代码  收藏代码
  1. public Configuration addProperties(Properties extraProperties) {  
  2.         this.properties.putAll( extraProperties );  
  3.         return this;  
  4.     }  

properties是Configuration类的内部对象。
于是session-factory节点就这么被加进去了。

这个properties是个很重要的变量, 在后面的ServiceRegistry创建的时候就会被用到。

--
可以看到这里的返回参数几乎都是Configuration, 弄来弄去, 最后都是在修改这个Configuration类的实例对象。
还是最初那行代码
Configuration con=new Configuration().configure(); 
说白了, 这里的configure()就是调用了一大堆内部外部方法, 将new出来的Configuration实例进行了加工, 然后返回。。
0 0