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