过完五一长假,花了四天的时间来学习Hibernate框架的使用,作为门外汉,先是从sourceforg.net下载 Hibernate3.2,先看官方文档,只有一个提纲,了解了一下各个包的结构,便开始根据Toturial实践,基本掌握了它的使用方法之后,盟生了 实现自己的SessionFactory和ConnectionProvider的想法。
闲话少说,要实现我的SessionFactory和ConnectionProvider,不深入了解该体系结构是不行的,先从源代码分析开始: 首先从org.hibernate.cfg.Configuration.java开始,使用Hibernate框架实现应用程序,首先就要与org.hibernate.cfg.Configuration打交道,要使用
Configuration.buildSessionFactory()方法获得一个SessionFactory,截取代码片段如下:
上面的代码片断省略了读取Hibernate配置的代码,从这个我们可以知道,Configuration类buildSessionFactory()方法实际上返回了SessionFactory接口的实现SessionFactoryImpl。
当我们得到了一个SessionFactory接口的实现SessionFactoryImpl,就要调用它的getCurrentSession()方 法来获得一个Session,接下来转到org.hibernate.impl.SessionFactoryImpl.java,来看看 getCurrentSession()方法的实现,代码片段如下:
在该方法中,SessionFactoryImpl将获得Session的工作委托给了currentSessionContext.currentSession(),currentSessionContext为何物?其定义为:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的构造函数中,可以看到:
马上追溯到buildCurrentSessionContext()方法,代码片段如下:
从这里可以发现,SessionFactoryImpl用反射实现了CurrentSessionContext接口的动态装配。
接下来,暂时将视线从SessionFactoryImpl移开,以org.hibernate.context.JTASessionContext为代表,看CurrentSessionContext接口是如何实现
的currentSession()方法的,打开org.hibernate.context.JTASessionContext.java,找到currentSession(),代码片段如下:
转移到buildOrObtainSession()方法,
闲话少说,要实现我的SessionFactory和ConnectionProvider,不深入了解该体系结构是不行的,先从源代码分析开始: 首先从org.hibernate.cfg.Configuration.java开始,使用Hibernate框架实现应用程序,首先就要与org.hibernate.cfg.Configuration打交道,要使用
Configuration.buildSessionFactory()方法获得一个SessionFactory,截取代码片段如下:
1
public
SessionFactorybuildSessionFactory()
throws
HibernateException
{
2
3 return new SessionFactoryImpl(
4 this ,
5 mapping,
6 settings,
7 getInitializedEventListeners()
8 );
9 }
2
3 return new SessionFactoryImpl(
4 this ,
5 mapping,
6 settings,
7 getInitializedEventListeners()
8 );
9 }
上面的代码片断省略了读取Hibernate配置的代码,从这个我们可以知道,Configuration类buildSessionFactory()方法实际上返回了SessionFactory接口的实现SessionFactoryImpl。
当我们得到了一个SessionFactory接口的实现SessionFactoryImpl,就要调用它的getCurrentSession()方 法来获得一个Session,接下来转到org.hibernate.impl.SessionFactoryImpl.java,来看看 getCurrentSession()方法的实现,代码片段如下:
1
public
org.hibernate.classic.SessiongetCurrentSession()
throws
HibernateException
{
2 if (currentSessionContext == null ) {
3 throw new HibernateException( " NoCurrentSessionContextconfigured! " );
4 }
5 return currentSessionContext.currentSession();
6 }
2 if (currentSessionContext == null ) {
3 throw new HibernateException( " NoCurrentSessionContextconfigured! " );
4 }
5 return currentSessionContext.currentSession();
6 }
在该方法中,SessionFactoryImpl将获得Session的工作委托给了currentSessionContext.currentSession(),currentSessionContext为何物?其定义为:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的构造函数中,可以看到:
currentSessionContext
=
buildCurrentSessionContext();
马上追溯到buildCurrentSessionContext()方法,代码片段如下:
1
private
CurrentSessionContextbuildCurrentSessionContext()
{
2 Stringimpl = properties.getProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS);
3 // forbackward-compatability
4 if (impl == null && transactionManager != null ) {
5 impl = " jta " ;
6 }
7
8 if (impl == null ) {
9 return null ;
10 }
11 else if ( " jta " .equals(impl)) {
12 if (settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions()) {
13 log.warn( " JTASessionContextbeingusedwithJDBCTransactionFactory;auto-flushwillnotoperatecorrectlywithgetCurrentSession() " );
14 }
15 return new JTASessionContext( this );
16 }
17 else if ( " thread " .equals(impl)) {
18 return new ThreadLocalSessionContext( this );
19 }
20 else if ( " managed " .equals(impl)) {
21 return new ManagedSessionContext( this );
22 }
23 else {
24 try {
25 ClassimplClass = ReflectHelper.classForName(impl);
26 return (CurrentSessionContext)implClass
27 .getConstructor( new Class[] {SessionFactoryImplementor. class } )
28 .newInstance( new Object[] { this } );
29 }
30 catch (Throwablet) {
31 log.error( " Unabletoconstructcurrentsessioncontext[ " + impl + " ] " ,t);
32 return null ;
33 }
34 }
35 }
36
2 Stringimpl = properties.getProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS);
3 // forbackward-compatability
4 if (impl == null && transactionManager != null ) {
5 impl = " jta " ;
6 }
7
8 if (impl == null ) {
9 return null ;
10 }
11 else if ( " jta " .equals(impl)) {
12 if (settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions()) {
13 log.warn( " JTASessionContextbeingusedwithJDBCTransactionFactory;auto-flushwillnotoperatecorrectlywithgetCurrentSession() " );
14 }
15 return new JTASessionContext( this );
16 }
17 else if ( " thread " .equals(impl)) {
18 return new ThreadLocalSessionContext( this );
19 }
20 else if ( " managed " .equals(impl)) {
21 return new ManagedSessionContext( this );
22 }
23 else {
24 try {
25 ClassimplClass = ReflectHelper.classForName(impl);
26 return (CurrentSessionContext)implClass
27 .getConstructor( new Class[] {SessionFactoryImplementor. class } )
28 .newInstance( new Object[] { this } );
29 }
30 catch (Throwablet) {
31 log.error( " Unabletoconstructcurrentsessioncontext[ " + impl + " ] " ,t);
32 return null ;
33 }
34 }
35 }
36
从这里可以发现,SessionFactoryImpl用反射实现了CurrentSessionContext接口的动态装配。
接下来,暂时将视线从SessionFactoryImpl移开,以org.hibernate.context.JTASessionContext为代表,看CurrentSessionContext接口是如何实现
的currentSession()方法的,打开org.hibernate.context.JTASessionContext.java,找到currentSession(),代码片段如下:
1
public
SessioncurrentSession()
throws
HibernateException
{
2
3 if (currentSession == null ) {
4 currentSession = buildOrObtainSession();
5
6 }
7
8 return currentSession;
9 }
2
3 if (currentSession == null ) {
4 currentSession = buildOrObtainSession();
5
6 }
7
8 return currentSession;
9 }
转移到buildOrObtainSession()方法,
1
protected
SessionbuildOrObtainSession()
{
2 return factory.openSession(
3 null ,
4 isAutoFlushEnabled(),
5 isAutoCloseEnabled(),
6 getConnectionReleaseMode()
7 );
8 }
2 return factory.openSession(
3 null ,
4 isAutoFlushEnabled(),
5 isAutoCloseEnabled(),
6 getConnectionReleaseMode()
7 );
8 }
前面SessionFactoryImpl.buildCurrentSessionContext()方法有new JTASessionContext( this ),而此时的factory.openSessio()就是SessionFactoryImpl.openSessio()了。
将目光焦点回到org.hibernate.impl.SessionFactoryImpl.java,SessionFactoryImpl.openSessio()的实现如下:
1
private
SessionImplopenSession(
2 Connectionconnection,
3 boolean autoClose,
4 long timestamp,
5 InterceptorsessionLocalInterceptor
6 ) {
7 return new SessionImpl(
8 connection,
9 this ,
10 autoClose,
11 timestamp,
12 sessionLocalInterceptor == null ? interceptor:sessionLocalInterceptor,
13 settings.getDefaultEntityMode(),
14 settings.isFlushBeforeCompletionEnabled(),
15 settings.isAutoCloseSessionEnabled(),
16 settings.getConnectionReleaseMode()
17 );
18 }
2 Connectionconnection,
3 boolean autoClose,
4 long timestamp,
5 InterceptorsessionLocalInterceptor
6 ) {
7 return new SessionImpl(
8 connection,
9 this ,
10 autoClose,
11 timestamp,
12 sessionLocalInterceptor == null ? interceptor:sessionLocalInterceptor,
13 settings.getDefaultEntityMode(),
14 settings.isFlushBeforeCompletionEnabled(),
15 settings.isAutoCloseSessionEnabled(),
16 settings.getConnectionReleaseMode()
17 );
18 }