MyBatisのソースコード解析:MapperRegistry

マッパーレジストラ(MapperRegistry)

   メモリマッパにすべてのインターフェイスを追加するためのレジストラマッパーは、マッパーが自身を登録二つの属性を維持し、コンフィグknownMappers、knownMappersはクラス<?>、MapperProxyFactory <?であることを特徴 > セット、パスがクラスに対応することを示していますMapperProxyFactoryが行う工場Mapperプロキシは、目的はMapperProxyで代理モデルを作成することで、比較的簡単で、MapperProxyは呼び出し()を介して指定されたメソッドマッパーインターフェースを呼び出すMapperProxyメソッドの実装を表すことになるのInvocationHandlerインタフェースを実現し、MapperProxyを直接実装しませんマッパーインターフェイスを呼び出しますが、内部的に、MapperMethod関連の包装方法SQLSESSIONを参照するには祭で<Mapper.Method、MapperMethod>マップのコレクションの維持MapperProxyので、基本的にちょうどプロキシ<方法、MapperMethod>間のマッピング関係

フォルダのレジストリ

登録、取得及びマッパーインターフェースは、主にいくつかの方法を提供し、登録された関数となっているかどうかを決定するためのMapperRegistry

マッパーインターフェースのセットに対応するバッファから取得1.getMapper(クラスタイプ、SQLSESSION SQLSESSION)
2.hasMapper(クラスタイプ)キャッシュセットはインターフェイスマッパーがあるか否かを判断する
3.addMapper(クラス型)インターフェイスマッパー収集knownMappersに加えた
4。 getMappers()が登録されているすべてのマッパーインタフェースのknownMappersコレクションを取得し、Mybatis3.2.2新しい
5.addMappers(文字列のpackageName、クラス<? >スーパータイプ)は、 パッケージまたはサブインターフェイスMybatis3.2.2の下にすべての適格スーパータイプのサブクラスを追加します。新しいです

  addMapper()メソッドを見て、この方法の主な役割は非常に重要なのは、収集後にマッパークラスを追加することがさらにしたマッパークラスマッピングマッパープロキシファクトリコードを達成するために設定knownMappersにマッパーを追加することで最初のXMLを完了しなければなりません解像度を設定し、解像度が失敗した場合、それはまだインターフェイスから削除マッパーなり、フォローアップはMapperAnnotationBuilderが解決されたかについてお話します。

1  公共 <T> ボイド addMapper(クラス<T> 型){
 2        // か否かを判断するインターフェース
。3      IF (type.isInterface()){
 4          // 既に登録されているか否かを判定する
。5        IF (hasMapper(タイプ)){
 6          スロー 新しい新 BindingException( "タイプ" +型+ "既にMapperRegistryすることが知られているに。" );
 7        }
 8。       ブール LoadCompleted = falseに図9        のtry {
 10            // インタフェースレジスタのセットをマッピングするマッパー
11。          knownMappers.put(タイプ、新しいですMapperProxyFactory <T> タイプ))。
12          // これは、パーサが実行される前に、タイプが追加されていることが重要です
 13          // そうでない場合は、自動的によって試みすることができる結合
 14          // マッパーパーサ。型がすでに知られている場合、それはしようとしません。
15          MapperAnnotationBuilderパーサー= 新しいMapperAnnotationBuilder(設定、タイプ)。
16          parser.parse()。
17          loadCompleted = 18        } 最後に{
 19          であれば(!loadCompleted){
 20            knownMappers.remove(タイプ)。
21          }
 22        }
 23      }
 24    }

getMapper(クラスタイプ、SQLSESSION SQLSESSION)

  あなたが未満を取得した場合は、プロキシ工場マッパーMapperProxyをインスタンス化するために使用され、私たちが言った最初で、これはMapperMethodを得るためには、knownMappersコレクションから直接マッパー既に登録、取得モードを取得するために使用される方法の究極の目標でありますつまり、プロキシ・ファクトリの一例として、引き出さマッパーMapperProxyFactory対応し、ダイナミックプロキシーモードProxyMapperをインスタンス化し、その目的は、マッパーのプロキシ実行方法のクラスを行う方法を達成することです。

 

1 @SuppressWarnings( "をチェック" 2    公共 <T> T getMapper(クラス<T> 型、SQLSESSION SQLSESSION){
 3。       この.notifyAll();
 4        // マッパープロキシファクトリを取得
5。     最終 MapperProxyFactory <T> = mapperProxyFactory(MapperProxyFactory <T> )knownMappers.get(タイプ);
 6      // マップにマッパークラスで来ないレジスタは、スローされるで見つからないBindingException 
。7      IF(mapperProxyFactory == NULL ){
 8        スロー 新しい新 BindingException( "タイプ" + +タイプの「MapperRegistryにすることが知られていません。」);
9      }
 10      試してみます{
 11          //のインスタンスを作成するために工場を使用し、エージェントは、本質的にBindingException中にスローされる例外を作成し、プロキシクラスのモデルを作成することによって発生
される12        戻りmapperProxyFactory.newInstance(SQLSESSION)を、
 13である      } キャッチ(例外E){
 14        スロー 新しい新 BindingException( "エラー原因マッパーのインスタンスを取得する:。" + E、E);
 15      }

 

MapperProxy

  mapperProxyは、ラッパークラスとしてカウントする必要があり、それ自身は何もしない、その主な役割は、<方法、MapperMethod>コレクションを維持するので、マッパーインタフェースは、SQL文を実行しようとしているものを知って、その後、SQLSESSIONに問い合わせを委託しますA。次のコードを参照してください、コード実行の流れは次のとおりです。

1.プロキシクラスが決定されるクラスかどうかどこ方法、それがある場合、この方法を直接実装。
2.デフォルトの方法は、それが以下の条件を決定するためのデフォルトの方法であるかどうか、行う場合の方法は、モードか否かを判断します

 

(method.getModifiers()
     &(Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC))== Modifier.PUBLIC
      && method.getDeclaringClass()isInterface()。

3.上記の二つのどれ場合、実行メソッドが呼び出され、前記キャッシュMapperMethodの対応するセットから除去されます。

  、使用してinvokeDefaultMethod()メソッドことに留意する必要がある@のUsesJava7アノテーションは最小バージョンはJDK7を使用する必要があることを示し、理由は、使用MethodHandlersのある反射と同じであるとすることができ、このクラスのフォローアップは今ちょうどそれを知っている必要があり、説明します、法と呼ばれます。

1  @Override
 2    公共オブジェクト呼び出しは、([]引数オブジェクト、プロキシ、メソッドメソッドオブジェクト)スローのThrowableを{
 3      のtry {
 4          // プロキシクラスがメソッドクラスであるかどうかを決定する
。5        IF(オブジェクト。クラス.equals(method.getDeclaringClass( ))){
 6            // 方法を実行
7。         復帰 Method.invoke(この、引数);
 8        } // それがデフォルトの方式であるか否かを判断
9。        のiF (isDefaultMethod(メソッド)){
 10            // デフォルトメソッドを呼び出す
11。         リターンinvokeDefaultMethod(プロキシ、方法、引数);
 12である       }
 13である      } キャッチ(ThrowableをT){
 14        ExceptionUtil.unwrapThrowable(T);
 15      }
 16      // 方法mapperMethod対応するキャッシュから除去
17。     最終 MapperMethod mapperMethod = cachedMapperMethod(方法) ;
 18      // ()メソッドを実行する実行
19。     リターンmapperMethod.execute(SQLSESSION、引数);
 20    }
1  UsesJava7 @
 2    プライベートオブジェクトinvokeDefaultMethod(オブジェクトプロキシ、方法方法、[]引数オブジェクト)
 図3は、       スローのThrowable {
 4      最終コンストラクタ<MethodHandles.Lookup>コンストラクタ= MethodHandles.Lookup。クラス
5          .getDeclaredConstructor(クラス。クラスint型クラス);
6      もし(!constructor.isAccessible()){
 7        constructor.setAccessible()。
8      }
 9つの     最終クラスdeclaringClass = <?> method.getDeclaringClass();
10      リターン・コンストラクタ
 11          .newInstance(declaringClass、
 12              MethodHandles.Lookup.PRIVATEは| MethodHandles.Lookup.PROTECTED
 13                  | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
 14          .unreflectSpecial(方法、declaringClass)
 15          .bindTo(プロキシ)
 16          .invokeWithArguments(引数)。
17    }

 

MapperRegistryの概要

  、MapperRegistry本質的マッパーインターフェースとアクセスMapperProxyクラスに登録MapperProxyとMapperProxyFactoryによってインスタンスしかしMapperProxyのinvoke()メソッドの呼び出しは、それに対応するインターフェイスに()メソッドMapperMethodマッパークラスを実行します。MapperRegistryマッパークラスパスに依存し、MapperProxy、MapperProxyFactory、ResolverUtil、MapperAnnotationBuilder他のコンポーネントを参照バインディングなどSQLSESSIONは、旅行を実行するための登録マッパーのSQL文を完成させます。

次の図は、関連するクラスMapperRegistryを示し

 

おすすめ

転載: www.cnblogs.com/zhengzuozhanglina/p/11234690.html