过完五一长假,花了四天的时间来学习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
public
SessionFactorybuildSessionFactory()
throws
HibernateException
{
2
3
return
new
SessionFactoryImpl(
4
this
,
5
mapping,
6
settings,
7
getInitializedEventListeners()
8
);
9
}

2



3

4

5

6

7

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

3

4

5

6

在该方法中,SessionFactoryImpl将获得Session的工作委托给了currentSessionContext.currentSession(),currentSessionContext为何物?其定义为:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的构造函数中,可以看到:


马上追溯到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

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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

4

5



6

7



8

9

转移到buildOrObtainSession()方法,
1
protected
SessionbuildOrObtainSession()
{
2
return
factory.openSession(
3
null
,
4
isAutoFlushEnabled(),
5
isAutoCloseEnabled(),
6
getConnectionReleaseMode()
7
);
8
}

2

3

4

5

6

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

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
