hibernate3之核心组件configuration

来源:互联网 发布:web php工程师招聘 编辑:程序博客网 时间:2024/06/15 18:14

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

如所示,通过指定路径加载相关的配置文件

其他方式加载配置文件方法如下所示:

我们也可以手动指定实体映射配置文件的加载,而不需要在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对象封装进了该子类的对象


0 0