過(guò)完五一長(zhǎng)假,花了四天的時(shí)間來(lái)學(xué)習(xí)Hibernate框架的使用,作為門外漢,先是從sourceforg.net下載Hibernate3.2,先看官方文檔,只有一個(gè)提綱,了解了一下各個(gè)包的結(jié)構(gòu),便開(kāi)始根據(jù)Toturial實(shí)踐,基本掌握了它的使用方法之后,盟生了實(shí)現(xiàn)自己的SessionFactory和ConnectionProvider的想法。
閑話少說(shuō),要實(shí)現(xiàn)我的SessionFactory和ConnectionProvider,不深入了解該體系結(jié)構(gòu)是不行的,先從源代碼分析開(kāi)始:
首先從org.hibernate.cfg.Configuration.java開(kāi)始,使用Hibernate框架實(shí)現(xiàn)應(yīng)用程序,首先就要與org.hibernate.cfg.Configuration打交道,要使用
Configuration.buildSessionFactory()方法獲得一個(gè)SessionFactory,截取代碼片段如下:
1
public SessionFactory buildSessionFactory() throws HibernateException
{
2


3
return new SessionFactoryImpl(
4
this,
5
mapping,
6
settings,
7
getInitializedEventListeners()
8
);
9
}
上面的代碼片斷省略了讀取Hibernate配置的代碼,從這個(gè)我們可以知道,Configuration類buildSessionFactory()方法實(shí)際上返回了SessionFactory接口的實(shí)現(xiàn)SessionFactoryImpl。
當(dāng)我們得到了一個(gè)SessionFactory接口的實(shí)現(xiàn)SessionFactoryImpl,就要調(diào)用它的getCurrentSession()方法來(lái)獲得一個(gè)Session,接下來(lái)轉(zhuǎn)到org.hibernate.impl.SessionFactoryImpl.java,來(lái)看看getCurrentSession()方法的實(shí)現(xiàn),代碼片段如下:
1
public org.hibernate.classic.Session getCurrentSession() throws HibernateException
{
2
if ( currentSessionContext == null )
{
3
throw new HibernateException( "No CurrentSessionContext configured!" );
4
}
5
return currentSessionContext.currentSession();
6
}
在該方法中,SessionFactoryImpl將獲得Session的工作委托給了currentSessionContext.currentSession(),currentSessionContext為何物?其定義為:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的構(gòu)造函數(shù)中,可以看到:
currentSessionContext = buildCurrentSessionContext();

馬上追溯到buildCurrentSessionContext()方法,代碼片段如下:
1
private CurrentSessionContext buildCurrentSessionContext()
{
2
String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
3
// for backward-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( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
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
Class implClass = ReflectHelper.classForName( impl );
26
return ( CurrentSessionContext ) implClass
27
.getConstructor( new Class[]
{ SessionFactoryImplementor.class } )
28
.newInstance( new Object[]
{ this } );
29
}
30
catch( Throwable t )
{
31
log.error( "Unable to construct current session context [" + impl + "]", t );
32
return null;
33
}
34
}
35
}
36
從這里可以發(fā)現(xiàn),SessionFactoryImpl用反射實(shí)現(xiàn)了CurrentSessionContext接口的動(dòng)態(tài)裝配。
接下來(lái),暫時(shí)將視線從SessionFactoryImpl移開(kāi),以org.hibernate.context.JTASessionContext為代表,看CurrentSessionContext接口是如何實(shí)現(xiàn)
的currentSession()方法的,打開(kāi)org.hibernate.context.JTASessionContext.java,找到currentSession(),代碼片段如下:
1
public Session currentSession() throws HibernateException
{
2


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


6
}
7


8
return currentSession;
9
}
轉(zhuǎn)移到buildOrObtainSession()方法,
1
protected Session buildOrObtainSession()
{
2
return factory.openSession(
3
null,
4
isAutoFlushEnabled(),
5
isAutoCloseEnabled(),
6
getConnectionReleaseMode()
7
);
8
}
前面SessionFactoryImpl.buildCurrentSessionContext()方法有new JTASessionContext( this ),而此時(shí)的factory.openSessio()就是SessionFactoryImpl.openSessio()了。
將目光焦點(diǎn)回到org.hibernate.impl.SessionFactoryImpl.java, SessionFactoryImpl.openSessio()的實(shí)現(xiàn)如下:
1
private SessionImpl openSession(
2
Connection connection,
3
boolean autoClose,
4
long timestamp,
5
Interceptor sessionLocalInterceptor
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
}