过完五一长假,花了四天的时间来学习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的构造函数中,可以看到:
currentSessionContext=buildCurrentSessionContext();
马上追溯到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
publicSessionFactorybuildSessionFactory()throwsHibernateException
{
2


3
returnnewSessionFactoryImpl(
4
this,
5
mapping,
6
settings,
7
getInitializedEventListeners()
8
);
9
}

publicSessionFactorybuildSessionFactory()throwsHibernateException
{2



3
returnnewSessionFactoryImpl(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
publicorg.hibernate.classic.SessiongetCurrentSession()throwsHibernateException
{
2
if(currentSessionContext==null)
{
3
thrownewHibernateException("NoCurrentSessionContextconfigured!");
4
}
5
returncurrentSessionContext.currentSession();
6
}

publicorg.hibernate.classic.SessiongetCurrentSession()throwsHibernateException
{2

if(currentSessionContext==null)
{3
thrownewHibernateException("NoCurrentSessionContextconfigured!");4
}5
returncurrentSessionContext.currentSession();6
}
在该方法中,SessionFactoryImpl将获得Session的工作委托给了currentSessionContext.currentSession(),currentSessionContext为何物?其定义为:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的构造函数中,可以看到:
currentSessionContext=buildCurrentSessionContext();
马上追溯到buildCurrentSessionContext()方法,代码片段如下:
1
privateCurrentSessionContextbuildCurrentSessionContext()
{
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
returnnull;
10
}
11
elseif("jta".equals(impl))
{
12
if(settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions())
{
13
log.warn("JTASessionContextbeingusedwithJDBCTransactionFactory;auto-flushwillnotoperatecorrectlywithgetCurrentSession()");
14
}
15
returnnewJTASessionContext(this);
16
}
17
elseif("thread".equals(impl))
{
18
returnnewThreadLocalSessionContext(this);
19
}
20
elseif("managed".equals(impl))
{
21
returnnewManagedSessionContext(this);
22
}
23
else
{
24
try
{
25
ClassimplClass=ReflectHelper.classForName(impl);
26
return(CurrentSessionContext)implClass
27
.getConstructor(newClass[]
{SessionFactoryImplementor.class})
28
.newInstance(newObject[]
{this});
29
}
30
catch(Throwablet)
{
31
log.error("Unabletoconstructcurrentsessioncontext["+impl+"]",t);
32
returnnull;
33
}
34
}
35
}
36

privateCurrentSessionContextbuildCurrentSessionContext()
{2
Stringimpl=properties.getProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS);3
//forbackward-compatability4

if(impl==null&&transactionManager!=null)
{5
impl="jta";6
}7

8

if(impl==null)
{9
returnnull;10
}11

elseif("jta".equals(impl))
{12

if(settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions())
{13
log.warn("JTASessionContextbeingusedwithJDBCTransactionFactory;auto-flushwillnotoperatecorrectlywithgetCurrentSession()");14
}15
returnnewJTASessionContext(this);16
}17

elseif("thread".equals(impl))
{18
returnnewThreadLocalSessionContext(this);19
}20

elseif("managed".equals(impl))
{21
returnnewManagedSessionContext(this);22
}23

else
{24

try
{25
ClassimplClass=ReflectHelper.classForName(impl);26
return(CurrentSessionContext)implClass27

.getConstructor(newClass[]
{SessionFactoryImplementor.class})28

.newInstance(newObject[]
{this});29
}30

catch(Throwablet)
{31
log.error("Unabletoconstructcurrentsessioncontext["+impl+"]",t);32
returnnull;33
}34
}35
}36
从这里可以发现,SessionFactoryImpl用反射实现了CurrentSessionContext接口的动态装配。
接下来,暂时将视线从SessionFactoryImpl移开,以org.hibernate.context.JTASessionContext为代表,看CurrentSessionContext接口是如何实现
的currentSession()方法的,打开org.hibernate.context.JTASessionContext.java,找到currentSession(),代码片段如下:
1
publicSessioncurrentSession()throwsHibernateException
{
2


3
if(currentSession==null)
{
4
currentSession=buildOrObtainSession();
5


6
}
7


8
returncurrentSession;
9
}

publicSessioncurrentSession()throwsHibernateException
{2



3

if(currentSession==null)
{4
currentSession=buildOrObtainSession();5



6
}7



8
returncurrentSession;9
}
转移到buildOrObtainSession()方法,
1
protectedSessionbuildOrObtainSession()
{
2
returnfactory.openSession(
3
null,
4
isAutoFlushEnabled(),
5
isAutoCloseEnabled(),
6
getConnectionReleaseMode()
7
);
8
}

protectedSessionbuildOrObtainSession()
{2
returnfactory.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
privateSessionImplopenSession(
2
Connectionconnection,
3
booleanautoClose,
4
longtimestamp,
5
InterceptorsessionLocalInterceptor
6
)
{
7
returnnewSessionImpl(
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
}
privateSessionImplopenSession(2
Connectionconnection,3
booleanautoClose,4
longtimestamp,5
InterceptorsessionLocalInterceptor6

)
{7
returnnewSessionImpl(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
}
本文详细解析了Hibernate框架的内部机制,特别是SessionFactory和CurrentSessionContext的实现细节。
1043

被折叠的 条评论
为什么被折叠?



