解析hibernate的源码,首先看的就是这个Configuration类。初学hibernate时,有这么一段小程序,用来获得sessionFactory的。请看下面这段代码:
private static SessionFactory sf = null;
static{
Configuration configuration = new Configuration();
configuration.configure("cn/huawei/config/hibernate.cfg.xml");
configuration.addClass(Customer.class);
sf = configuration.buildSessionFactory();
}
这是初学hibernate时写的一个HibernateUtils帮助类,相信很多人对这个帮助类很熟悉,有的人可能封装的更好一点。这段代码的含义就是代码启动时拿到hibernate的配置文件,然后获得sessionFactory实例。
下面我们就来看下这个Configuration类是如何做的?看下面的代码
public class Configuration implements Serializable {
/[1]
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
//[2]
public Configuration configure(String resource) throws HibernateException {
log.info( "configuring from resource: " + resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
//[3]
protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
org.dom4j.Document doc;
try {
List errors = new ArrayList();
doc = xmlHelper.createSAXReader( resourceName, errors, entityResolver )
.read( new InputSource( stream ) );
if ( errors.size() != 0 ) {
throw new MappingException(
"invalid configuration",
(Throwable) errors.get( 0 )
);
}
}
catch (DocumentException e) {
throw new HibernateException(
"Could not parse configuration: " + resourceName,
e
);
}
finally {
try {
stream.close();
}
catch (IOException ioe) {
log.warn( "could not close input stream for: " + resourceName, ioe );
}
}
return doConfigure( doc );
}
//[4]
protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
Element sfNode = doc.getRootElement().element( "session-factory" );
String name = sfNode.attributeValue( "name" );
if ( name != null ) {
properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
}
addProperties( sfNode );
parseSessionFactory( sfNode, name );
Element secNode = doc.getRootElement().element( "security" );
if ( secNode != null ) {
parseSecurity( secNode );
}
log.info( "Configured SessionFactory: " + name );
log.debug( "properties: " + properties );
return this;
}
//.......好多代码的....省略了
}
看第一个方法【1】看出程序默认给的配置文件名称是hibernate.cfg.xml。如果在帮助类中不给出配置文件的路径的话,Hibernate启动时会自己到源包路径去找Hibernate.cfg.xml的配置文件,如果找不到或者解析不了的话,程序会报出异常,上面给出的方法很明了,直接可以看出方法调用的顺序:首先不给出配置文件的路径的话Hibernate会首先调用configure()方法,接着在configure()中程序会直接调用有参的方法configure(String resource);接着在这个有参的方法中去调用doConfigure(InputStream inputStream,String resourceName)这个方法,然后解析这个Hibernate的配置文件。将其中的获取的配置值放置到Properties这个变量中。下面有一段代码是放置配置属性的值的,看:
private void addProperties(Element parent) {
Iterator iter = parent.elementIterator( "property" );
while ( iter.hasNext() ) {
Element node = (Element) iter.next();
String name = node.attributeValue( "name" );
String value = node.getText().trim();
log.debug( name + "=" + value );
properties.setProperty( name, value );
if ( !name.startsWith( "hibernate" ) ) {
properties.setProperty( "hibernate." + name, value );
}
}
Environment.verifyProperties( properties );
}