序文 インターセプターの機能の 1 つは、特定のメソッドの呼び出しをインターセプトできることです。インターセプトされたメソッドの実行の前後にロジックを追加することも、インターセプトされたメソッドを実行する代わりに、インターセプトされたメソッドを実行するときに独自のロジックを実行することもできます。 Mybatis インターセプターを設計した当初の目的の 1 つは、Mybatis の固有のロジックを変更することなく、ユーザーが特定のタイミングで独自のロジックを実装できるようにすることです。たとえば、すべての SQL に対して固定操作を実行したり、SQL クエリに対してセキュリティ チェックを実行したり、関連する SQL クエリ ログを記録したりしたいとします。 Mybatis は、カスタム インターセプターを実装できる Interceptor インターフェースを提供します。 パブリックインターフェースインターセプター{ オブジェクト intercept(Invocation invocation) は Throwable をスローします。 オブジェクトプラグイン(オブジェクトターゲット); void setProperties(プロパティプロパティ); } インターフェースには3つのメソッド定義が含まれています インターセプトメソッドは、インターセプトオブジェクトに対する特定の処理メソッドです。渡される Invocation には、インターセプト対象クラスの強度、インターセプトメソッド、およびメソッドの入力パラメータグループが含まれます。呼び出し手順を使用して元の関数を実行します。 プラグインはインターセプトするかどうかを決定します。インターセプトが不要な場合は、ターゲットが直接返されます。インターセプトが必要な場合は、Plugin クラスの wrap 静的メソッドが呼び出されます。現在のインターセプターがインターフェイスを実装している場合はプロキシ オブジェクトが返され、そうでない場合は直接返されます (プロキシ モードの設計を思い出してください)。プロキシ オブジェクトは、実際には InvocationHandler インターフェイスを実装する Plugin クラスのインスタンスです。InvocationHandler インターフェイスには、コールバック メソッドの呼び出しメソッドのみが含まれます。 プロキシ オブジェクトのインターフェイス メソッドが実行されると、プラグインの呼び出しメソッドが呼び出され、実行されるオブジェクト、メソッド、およびパラメーターが呼び出しオブジェクトにパッケージ化され、インターセプターのインターセプト メソッドに渡されます。呼び出しは、インターセプトされた元のメソッドを実行するための procced メソッドを定義します。 プラグインクラスの定義 パブリッククラスPluginはInvocationHandlerを実装します{ プライベートオブジェクトターゲット; プライベートインターセプターインターセプター; プライベート Map、Set> signatureMap; プライベートプラグイン(オブジェクトターゲット、インターセプターインターセプター、マップ、Set> signatureMap) { this.target = ターゲット; this.interceptor = インターセプター; this.signatureMap = 署名マップ; } パブリック静的オブジェクトラップ(オブジェクトターゲット、インターセプターインターセプター) { マップ、セット> signatureMap = getSignatureMap(インターセプター); クラスタイプ = target.getClass(); クラス[]インターフェース = getAllInterfaces(type, signatureMap); インターフェースの長さが0より大きい場合 Proxy.newProxyInstance() を返します。 type.getClassLoader()、 インターフェース、 新しいプラグイン(ターゲット、インターセプター、シグネチャマップ)); } ターゲットを返します。 } パブリックオブジェクトinvoke(オブジェクトプロキシ、メソッドメソッド、オブジェクト[]引数)throwsThrowable{ 試す { メソッドを signatureMap.get(method.getDeclaringClass()); に設定します。 メソッドが null の場合、methods.contains(method) は次のように記述されます。 interceptor.intercept(new Invocation(target, method, args)) を返します。 } メソッドを呼び出します(ターゲット、引数)。 } キャッチ (例外 e) { ExceptionUtil.unwrapThrowable(e) をスローします。 } } プライベート静的マップ、Set> getSignatureMap(インターセプターインターセプター) { インターセプト interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class); if (interceptsAnnotation == null) { // 問題 #251 throw new PluginException("インターセプターに @Intercepts アノテーションが見つかりません " + interceptor.getClass().getName()); } 署名[] sigs = interceptsAnnotation.value(); Map、Set> signatureMap = new HashMap、Set>(); (署名 sig : sigs) { メソッドを設定します = signatureMap.get(sig.type()); if (メソッド == null) { メソッド = 新しい HashSet(); signatureMap.put(sig.type(), メソッド); } 試す { メソッド method = sig.type().getMethod(sig.method(), sig.args()); メソッドを追加します。 } キャッチ (NoSuchMethodException e) { throw new PluginException("" + sig.type() + " に " + sig.method() + " という名前のメソッドが見つかりませんでした。原因: " + e, e); } } 署名マップを返します。 } プライベート静的Class[] getAllInterfaces(クラス型、マップ、セット> signatureMap) { Set> インターフェース = new HashSet>(); while (type != null) { (クラスcの場合: type.getInterfaces()) { 署名マップにキーが含まれている場合(c) インターフェースを追加します。 } } タイプ = type.getSuperclass(); } 戻り値:interfaces.toArray(新しいClass[interfaces.size()]); } } setProperties メソッドは、その名前が示すように、プロパティを設定するために使用されます。 Bean プロパティを初期化する方法は多数ありますが、これはその 1 つです。 Mybatis は、現在のクラスがインターセプターであることを宣言するための @Intercepts アノテーションを提供します。その値は @Signature 配列であり、インターセプトされるインターフェース、メソッド、および対応するパラメーター タイプを示します。 @Intercepts({@Signature(メソッド = "準備"、タイプ = StatementHandler.class、引数 = {Connection.class})、 @Signature(メソッド = "query"、タイプ = StatementHandler.class、引数 = {java.sql.Statement.class、ResultHandler.class})}) パブリッククラス TenantInterceptor は Interceptor を実装します { ..... たとえば、上記のクラス宣言では、最初の Signature アノテーションは StatementHandler クラスの下にある入力パラメータ (prepare という名前の Connection メソッド) をインターセプトします。 2 番目の Signature アノテーションは、2 つの入力パラメータ (Statement 型と ResultHandler 型) を含む StatementHandler クラスのクエリ メソッドをインターセプトします。 最後に、宣言された Interceptor を有効にするには、mybatis プラグに登録する必要があります。 <!-- mybatis を設定する --> <bean id="sqlSessionFactory" クラス="org.mybatis.spring.SqlSessionFactoryBean"> <プロパティ名="データソース" ref="データソース"/> <プロパティ名="configLocation" 値="classpath:mybatis/mybatis-config.xml"/> <!-- マッパースキャン --> <プロパティ名="mapperLocations" 値="classpath:mybatis/*/*.xml"/> <プロパティ名="プラグイン"> <配列> <!-- 独自のインターセプターを登録する --> <bean id="paginationInterceptor" class="xxx.xxx.TenantInterceptor"> </bean> </配列> </プロパティ> </bean> 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: 実際のプロジェクトでElementUIを使用する手順の詳細な説明
まず設定ファイルがどこにあるか調べる nginx.confはどこにありますかこれらのディレクトリを調...
<br />構造と階層により複雑さが軽減され、読みやすさが向上します。記事やサイトが整理...
プロジェクトのテスト環境データベースのデータが失われてしまったので、記録しておきたいと思います。当時...
まず、nginx コンテナ内の構造:コンテナを入力します: docker exec -it b511...
Linux システムには 2 種類のスケジュールされたタスクがあります。1 つは 1 回だけ実行され...
序文私が使用しているパソコンはMacで、OSはmacOS Mojaveです。コンピュータに仮想マシン...
システム環境: Ubuntu 16.04LTSこの記事では、6 つの Docker コンテナを使用し...
Dockerはプライベートレジストリ内のイメージを照会または取得するために、 docker 検索 1...
複合インデックス (結合インデックスとも呼ばれます) は、複数の列に対して作成されるインデックスです...
nginx Nginx (エンジン x) は、高性能な HTTP およびリバース プロキシ サーバー...
目次k8sのコントローラータイプポッドとコントローラの関係デプロイメント(ステートレスアプリケーショ...
複雑なテーブル構造では、一部のセルが水平方向に複数のセルにまたがるため、行間属性 ROWSPAN を...
1. redisイメージを検索する docker 検索 redis 2. Redisイメージをダウン...
仕事のプロジェクトのニーズにより、曲の再生が必要となり、さまざまな資料を参考にして、NetEase ...
1. はじめに: mysql8以降は、これまでよく使われていたバージョンと比べてかなり変更点が大きい...