天天看點

hibernate3之核心元件configuration

Configuration:

作用一:

預設加載hibernate配置檔案

//獲得配置對象并加載配置檔案

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

configure()方法内部實作如下:
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
public Configuration configure(String resource) throws HibernateException {
log.info( "configuring from resource: " + resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
通過以上源碼,我們可以知道,configure()内部加載讀取hibernate.cfg.xml檔案的位置,預設是在src目錄下。并且加載時是通過一個封裝的位元組輸入流方法來讀取該指定位置上的配置檔案資訊,并傳回doConfigure()方法的傳回值
1.加載流:
我們再來看一下getConfigurationInputStream( resource )方法的内部實作:
protected InputStream getConfigurationInputStream(String resource) throws HibernateException {
log.info( "Configuration resource: " + resource );
return ConfigHelper.getResourceAsStream( resource );
}
該方法内部調用了config工具類ConfigHelper的getResourceAsStream( resource )方法
ConfigHelper:
public static InputStream getResourceAsStream(String resource) {

//判斷路徑是否以“/”開頭,是則截去“/”

String stripped = resource.startsWith("/") ?

resource.substring(1) : resource;

//擷取目前線程的類加載器,調用getResourceAsStream加載檔案資訊到流中

InputStream stream = null;

ClassLoader classLoader = Thread.currentThread().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;

}
2.傳回值doConfigure(stream, resource)

protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {

try {

List errors = new ArrayList();

//調用xml解析工具類從流中讀取配置檔案資訊封裝到document中

Document document = xmlHelper.createSAXReader( resourceName, errors, entityResolver )

.read( new InputSource( stream ) );

if ( errors.size() != 0 ) {

throw new MappingException( "invalid configuration", (Throwable) errors.get( 0 ) );

}

doConfigure( document );

}

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 );

}

}

//傳回目前configure對象

return this;

}
加載指定路徑下的配置檔案:

//獲得配置對象

Configuration configure = new  Configuration("/com/zrgk/util/hibernate.cfg.xml");

如所示,通過指定路徑加載相關的配置檔案

其他方式加載配置檔案方法如下所示:

hibernate3之核心元件configuration
我們也可以手動指定實體映射配置檔案的加載,而不需要在hibernate.cfg.xml中添加相應配置,如下:

Configuration configure = new 

Configuration().configure("/com/zrgk/util/hibernate.cfg.xml").addResource("com/zrgk/pojo/User.hbm.xml");

其中要注意一點:User.hbm.xml的路徑不能以“/”開頭,因為addResource()方法内部沒有對該情況進行判斷

通過這個,我們也可以發現,這是一種鍊式程式設計,而configure()内部傳回this,正是這種程式設計方式的代碼展現

作用二:

獲得SessionFactory工廠

//獲得會話工廠

SessionFactory sessionFactory = configure.buildSessionFactory();

源碼:

public SessionFactory buildSessionFactory() throws HibernateException {

log.debug( "Preparing to build session factory with filters : " + filterDefinitions );

secondPassCompile();

if ( ! metadataSourceQueue.isEmpty() ) {

log.warn( "mapping metadata cache was not completely processed" );

}

enableLegacyHibernateValidator();

enableBeanValidation();

enableHibernateSearch();

validate();

Environment.verifyProperties( properties );

Properties copy = new Properties();

copy.putAll( properties );

PropertiesHelper.resolvePlaceHolders( copy );

Settings settings = buildSettings( copy );

return new SessionFactoryImpl(

this,

mapping,

settings,

getInitializedEventListeners(),

sessionFactoryObserver

);

}
通過源碼,我們隻需要知道,最終傳回的是SessionFactory的子類實作,并将configure對象封裝進了該子類的對象

繼續閱讀