在使用hibernate的时候,需要创建一个configuration对象来加载xml文件
Configuration configuration = new Configuration();
configuration.configure();
我们来跟一下configure方法
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
public Configuration configure(String resource) throws HibernateException {
LOG.configuringFromResource( resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
有两个方法,一个没有参数,一个有参数,可以发现,其实没有参数的configure方法也是调用了有参数的configure方法,参数为"hibernate.cfg.xml",所以,如果你调用了没有参数的configure方法,那么就要把xml文件放到src下面,否则就要把xml文件的目录作为参数传进去
不管LOG,这里有两个方法被执行了
1.InputStream stream = getConfigurationInputStream(resource);
protected InputStream getConfigurationInputStream(String resource) throws HibernateException {
LOG.configurationResource( resource );
return ConfigHelper.getResourceAsStream( resource );
}
继续看ConfigHelper.getResourceAsStream(resource);
public static InputStream getResourceAsStream(String resource) {
String stripped = resource.startsWith("/") ?
resource.substring(1) : resource;
InputStream stream = null;
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
if (classLoader!=null) {
stream = classLoader.getResourceAsStream( stripped );
}
if ( stream == null ) {
stream = Environment.class.getResourceAsStream( resource );
}
if ( stream == null ) {
stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
}
if ( stream == null ) {
throw new HibernateException( resource + " not found" );
}
return stream;
}
到了这里,就获取了xml的stream
2.doConfigure( stream, resource );
protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
try {
ErrorLogger errorLogger = new ErrorLogger( resourceName );
Document document = xmlHelper.createSAXReader( errorLogger, entityResolver )
.read( new InputSource( stream ) );
if ( errorLogger.hasErrors() ) {
throw new MappingException( "invalid configuration", errorLogger.getErrors().get( 0 ) );
}
doConfigure( document );
}
catch (DocumentException e) {
throw new HibernateException( "Could not parse configuration: " + resourceName, e );
}
finally {
try {
stream.close();
}
catch (IOException ioe) {
LOG.unableToCloseInputStreamForResource( resourceName, ioe );
}
}
return this;
}
可以看到,使用SAX解析了xml文件,然后执行了doConfigure(document);
看一下doConfigure方法
protected Configuration doConfigure(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.configuredSessionFactory( name );
LOG.debugf( "Properties: %s", properties );
return this;
}
到了这里,我们可以看到,sfNode获得了xml中<session-factory>节点的内容,然后执行了addProperties(sfnode)
private void addProperties(Element parent) {
Iterator itr = parent.elementIterator( "property" );
while ( itr.hasNext() ) {
Element node = (Element) itr.next();
String name = node.attributeValue( "name" );
String value = node.getText().trim();
LOG.debugf( "%s=%s", name, value );
properties.setProperty( name, value );
if ( !name.startsWith( "hibernate" ) ) {
properties.setProperty( "hibernate." + name, value );
}
}
Environment.verifyProperties( properties );
}
通过迭代之后,把所有属性加载完毕。