Hibernate源代码分析(一):设计属于我的Session

系统 1419 0
过完五一长假,花了四天的时间来学习Hibernate框架的使用,作为门外汉,先是从sourceforg.net下载 Hibernate3.2,先看官方文档,只有一个提纲,了解了一下各个包的结构,便开始根据Toturial实践,基本掌握了它的使用方法之后,盟生了 实现自己的SessionFactory和ConnectionProvider的想法。
闲话少说,要实现我的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 }

上面的代码片断省略了读取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 }

在该方法中,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

从这里可以发现,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 }

转移到buildOrObtainSession()方法,

1 protected SessionbuildOrObtainSession() {
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 }

Hibernate源代码分析(一):设计属于我的SessionFactory和ConnectionProvider


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论