亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

mybatis源碼分析(3)——SqlSessionManager類

系統(tǒng) 1859 0

mybatis源碼分析(3)——SqlSessionManager類

從上圖可能看出,在?mybatis 中, SqlSession 的實(shí)現(xiàn)類有兩個(gè),其中 SqlSessionManager 類不但實(shí)現(xiàn)了 SqlSession 接口,同時(shí)也實(shí)現(xiàn)了 SqlSessionFactory 接口。那么 SqlSessionManager 類究竟有何作用? ?? 由于源碼中缺少注釋,所以從 mybatis 目前的提供官方文檔來看,似乎該類已被棄用,其功能被 DefaultSqlSession 類和 DefaultSqlSessionFactory 類所代替。只是該類的部分代碼對我們理解 mybatis 的一些底層機(jī)制還具有一定的參考價(jià)值,例如:

SqlSessionManager的下面的構(gòu)造方法,會(huì)產(chǎn)生一個(gè)SqlSession 的一個(gè)代理對象:

?

      
        private
      
      
         SqlSessionManager(SqlSessionFactory sqlSessionFactory) {

    
      
      
        this
      
      .sqlSessionFactory =
      
         sqlSessionFactory;

    
      
      
        this
      
      .sqlSessionProxy =
      
         (SqlSession) Proxy.newProxyInstance(

        SqlSessionFactory.
      
      
        class
      
      
        .getClassLoader(),

        
      
      
        new
      
       Class[]{SqlSession.
      
        class
      
      
        },

        
      
      
        new
      
      
         SqlSessionInterceptor());

}
      
    

?

SqlSessionInterceptor類實(shí)現(xiàn)了InvocationHandler接口

      privaprivate 
      
        class
      
       SqlSessionInterceptor 
      
        implements
      
      
         InvocationHandler {

  
      
      
        public
      
       Object invoke(Object proxy, Method method, Object[] args) 
      
        throws
      
      
         Throwable   

  {

      
      
      
        final
      
       SqlSession sqlSession = SqlSessionManager.
      
        this
      
      
        .localSqlSession.get();

      
      
      
        if
      
       (sqlSession != 
      
        null
      
      
        ) {

        
      
      
        try
      
      
         {

          
      
      
        return
      
      
         method.invoke(sqlSession, args);

        } 
      
      
        catch
      
      
         (Throwable t) {

          
      
      
        throw
      
      
         ExceptionUtil.unwrapThrowable(t);

        }

      } 
      
      
        else
      
      
         {

        
      
      
        final
      
       SqlSession autoSqlSession =
      
         openSession();

        
      
      
        try
      
      
         {

          
      
      
        final
      
       Object result =
      
         method.invoke(autoSqlSession, args);

          autoSqlSession.commit();

          
      
      
        return
      
      
         result;

        } 
      
      
        catch
      
      
         (Throwable t) {

          autoSqlSession.rollback();

          
      
      
        throw
      
      
         ExceptionUtil.unwrapThrowable(t);

        } 
      
      
        finally
      
      
         {

          autoSqlSession.close();

        }

      }

    }

  }


      
      
        private
      
      
        class
      
       SqlSessionInterceptor 
      
        implements
      
      
         InvocationHandler {

  
      
      
        public
      
       Object invoke(Object proxy, Method method, Object[] args) 
      
        throws
      
      
         Throwable   

  {

      
      
      
        final
      
       SqlSession sqlSession = SqlSessionManager.
      
        this
      
      
        .localSqlSession.get();

      
      
      
        if
      
       (sqlSession != 
      
        null
      
      
        ) {

        
      
      
        try
      
      
         {

          
      
      
        return
      
      
         method.invoke(sqlSession, args);

        } 
      
      
        catch
      
      
         (Throwable t) {

          
      
      
        throw
      
      
         ExceptionUtil.unwrapThrowable(t);

        }

      } 
      
      
        else
      
      
         {

        
      
      
        final
      
       SqlSession autoSqlSession =
      
         openSession();

        
      
      
        try
      
      
         {

          
      
      
        final
      
       Object result =
      
         method.invoke(autoSqlSession, args);

          autoSqlSession.commit();

          
      
      
        return
      
      
         result;

        } 
      
      
        catch
      
      
         (Throwable t) {

          autoSqlSession.rollback();

          
      
      
        throw
      
      
         ExceptionUtil.unwrapThrowable(t);

        } 
      
      
        finally
      
      
         {

          autoSqlSession.close();

        }

      }

    }

  }
      
    

下面對這一段使用JAVA 動(dòng)態(tài) 代理技術(shù)產(chǎn)生SqlSession 代理對象的代碼進(jìn)行分析:

this.sqlSessionProxy?=?(SqlSession)?Proxy.newProxyInstance(

????????SqlSessionFactory.class.getClassLoader(),

????????new?Class[]{SqlSession.class},

????????new?SqlSessionInterceptor())??這句是關(guān)鍵, JDK Proxy 類的 newProxyInstance 方法的方法原型如下:

public?static?Object?newProxyInstance(ClassLoader?loader,

??Class<?>[]?interfaces,

??InvocationHandler?h)

throws?IllegalArgumentException

在調(diào)這個(gè)方法中需要傳入三個(gè)參數(shù):

??一個(gè) interfaces 的數(shù)組參數(shù)

??一個(gè) InvocationHanler? 接口的實(shí)例對象

??一個(gè)類加載器,

則Proxy.newProxyInstance方法執(zhí)行后會(huì)返回 interfaces 中任一接口的實(shí)例對象(假設(shè)該對象為 proxyObject), 那么當(dāng)我們在調(diào)用這個(gè)對象 proxyObject 的相應(yīng)方法時(shí),就會(huì)進(jìn)入到 InvocationHandler? 這個(gè)參數(shù)對象的 invoke(Object?proxy,?Method?method,?Object[]?args)方法中,或者換句話說,就會(huì)被h 這個(gè)對象的 invoke 方法攔截 ,? 對象 proxyObject 會(huì)作為

Invoke 中的 proxy 參數(shù), proxyObject 調(diào)用的方法的方法對象會(huì)作為 method 參數(shù) , 方法的參數(shù)會(huì)作為 args 參數(shù) ,這樣在 InvocationHandler? 對象的 invoke 方法中,就會(huì)通過 Method.invoke 方法來執(zhí)行具體的目標(biāo)對象的相應(yīng)方法,在 mybatis 的這個(gè)應(yīng)用場景上,這個(gè)目標(biāo)對象其實(shí)就是一個(gè) SqlSession 的實(shí)例 , 通過 SqlSessionManager 類的成員變量 sqlSessionFactory的openSession()獲得或者從當(dāng)前線程中獲取。

?

以上的實(shí)現(xiàn)技術(shù)主要就是使用了 java 的動(dòng)態(tài)代理技術(shù),看到網(wǎng)上不少人在問這個(gè) InvocationHandler? 接口中的 invoke 方法的第一個(gè)參數(shù) proxy 究竟有何作用,這個(gè) proxy 其實(shí)就是一個(gè)代理對象實(shí)例(通過 Proxy.newProxyInstance方法產(chǎn)生),下面就舉例說明一下它的作用:

可參照?java.rmi.server.RemoteObjectInvocationHandler類中的相應(yīng)方法invoke 方法,一個(gè)用法就是判斷 invoke method 參數(shù),看是否有必要調(diào)用 proxy 對象的其他方法,另一個(gè)用處就是作為參數(shù)把該對象提供給遠(yuǎn)程調(diào)用的方法使用。 ?

mybatis源碼分析(3)——SqlSessionManager類


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 农村女人十八毛片a级毛片 农村三级孕妇视频在线 | 国产麻豆精品hdvideoss | 成人在线视频国产 | 久久精品久久精品久久精品 | 国产成人亚洲精品乱码在线观看 | 国产成人免费视频精品一区二区 | 天天拍拍天天爽免费视频 | 国模和精品嫩模私拍视频 | 奇米影视首页 | 99久久精品毛片免费播放 | 国产精品v一区二区三区 | 久久久久久久综合日本亚洲 | 久久免费精品一区二区 | 激情五月五月婷婷 | 欧美激情久久久久久久久 | 亚洲一二三 | 国产精品伦理久久久久久 | 成人特级毛片69免费观看 | chinese456老人gay| 欧美日本高清视频在线观看 | 欧美a在线视频 | 亚洲美色综合天天久久综合精品 | 欧美日本亚洲国产一区二区 | 韩国三日本三级中文字幕 | 成人爽a毛片在线视频 | 图片专区亚洲欧美另类 | 一级毛片日本特黄97人人 | 国产成人久久综合二区 | 久久成人18免费 | 欧美一级精品高清在线观看 | 91精品国产免费久久国语麻豆 | 四虎海外在线永久免费看 | 天天操视频 夜夜 | 久久这里只有精品免费视频 | 亚洲日本香蕉视频 | 中文字幕一视频97色伦 | 成人午夜爽爽爽免费视频 | 97在线观看完整免费 | 视频日韩| 国产夫妻久久线观看 | 亚洲精品国产一区二区三 |