上一篇中: Hibernate源代码分析(一):设计属于我的SessionFactory和ConnectionProvider 分析到了SessionFactoryImpl.openSession()方法,该方法将其
职责委托给了SessionImpl,打开org.hibernate.impl.SessionImpl.java,看看实现代码:

 1     SessionImpl(
 2              final  Connection connection,
 3              final  SessionFactoryImpl factory,
 4              final   boolean  autoclose,
 5              final   long  timestamp,
 6              final  Interceptor interceptor,
 7              final  EntityMode entityMode,
 8              final   boolean  flushBeforeCompletionEnabled,
 9              final   boolean  autoCloseSessionEnabled,
10              final  ConnectionReleaseMode connectionReleaseMode)  {
11        super( factory );
12        this.rootSession = null;
13        this.timestamp = timestamp;
14        this.entityMode = entityMode;
15        this.interceptor = interceptor;
16        this.listeners = factory.getEventListeners();
17        this.actionQueue = new ActionQueue( this );
18        this.persistenceContext = new StatefulPersistenceContext( this );
19        this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
20        this.autoCloseSessionEnabled = autoCloseSessionEnabled;
21        this.connectionReleaseMode = connectionReleaseMode;
22        this.jdbcContext = new JDBCContext( this, connection, interceptor );
23
24        if ( factory.getStatistics().isStatisticsEnabled() ) {
25            factory.getStatisticsImplementor().openSession();
26        }

27
28        if ( log.isDebugEnabled() ) {
29            log.debug( "opened session at timestamp: " + timestamp );
30        }

31    }


      我们关注的就是数据库连接,重点关注第22行,在该行将Connection对象传递给了JDBCContext,通过观察前 面的代码我们可以发现,JTASessionContext.buildOrObtainSession() 方法传递的Connection对象为null,这个可以说,Connection对象的获得将由
ConnectionProvider接口的实现类来完成。

      接下来看看JDBCContent类的构造函数,跳转到org.hibernate.jdbc.JDBCContent.java,程序代码如下:

 1      public  JDBCContext(Context owner, Connection connection, Interceptor interceptor)  {
 2        this.owner = owner;
 3        this.connectionManager = new ConnectionManager(
 4                owner.getFactory(),
 5                this,
 6                owner.getConnectionReleaseMode(),
 7                connection,
 8                interceptor
 9            );
10
11        final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
12                || owner.isFlushBeforeCompletionEnabled()
13                || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
14        if ( registerSynchronization ) {
15            registerSynchronizationIfPossible();
16        }

17    }

      这段程序代码里创建了一个新的对象connectionManager,我们跟踪一下org.hibernate.jdbc.ConnectionManager.java,在这个文件里可以
发现一个方法openConnection(),代码如下:

 1      private   void  openConnection()  throws  HibernateException  {
 2        if ( connection != null ) {
 3            return;
 4        }

 5
 6        log.debug("opening JDBC connection");
 7        try {
 8            connection = factory.getConnectionProvider().getConnection();
 9        }

10        catch (SQLException sqle) {
11            throw JDBCExceptionHelper.convert(
12                    factory.getSQLExceptionConverter(),
13                    sqle,
14                    "Cannot open connection"
15                );
16        }

17
18        callback.connectionOpened(); // register synch; stats.connect()
19    }

      现在,最有价值的发现出来了,在第8行,这里就是从缓冲池获得数据库连接的代码。

      接下来我们可以设计实现ConnectionProvider的具体类了。
 
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐