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

来源:互联网 发布:java zookeeper 注册 编辑:程序博客网 时间:2024/05/16 14:03
 过完五一长假,花了四天的时间来学习Hibernate框架的使用,作为门外汉,先是从sourceforg.net下载 Hibernate3.2,先看官方文档,只有一个提纲,了解了一下各个包的结构,便开始根据Toturial实践,基本掌握了它的使用方法之后,盟生了 实现自己的SessionFactory和ConnectionProvider的想法。
         闲话少说,要实现我的SessionFactory和ConnectionProvider,不深入了解该体系结构是不行的,先从源代码分析开始:          首先从org.hibernate.cfg.Configuration.java开始,使用Hibernate框架实现应用程序,首先就要与org.hibernate.cfg.Configuration打交道,要使用
Configuration.buildSessionFactory()方法获得一个SessionFactory,截取代码片段如下:
         
         
1public SessionFactory buildSessionFactory() 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.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的构造函数中,可以看到:

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

         从这里可以发现,SessionFactoryImpl用反射实现了CurrentSessionContext接口的动态装配。
         接下来,暂时将视线从SessionFactoryImpl移开,以org.hibernate.context.JTASessionContext为代表,看CurrentSessionContext接口是如何实现
的currentSession()方法的,打开org.hibernate.context.JTASessionContext.java,找到currentSession(),代码片段如下:

1    public Session currentSession() throws HibernateException {
2
3if ( currentSession == null ) {
4            currentSession = buildOrObtainSession();
5
6}

7
8return currentSession;
9}

        转移到buildOrObtainSession()方法,

1    protected Session buildOrObtainSession() {
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 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    }
       
原创粉丝点击