序文 インターセプターの機能の 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を使用する手順の詳細な説明
この記事では、参考までに、簡単な抽選機能を実装するためのjsの具体的なコードを共有します。具体的な内...
1. GitLabの紹介Gitlab 公式アドレス: https://about.gitlab.co...
導入MySQL データベースを使用する場合、int を主キーとして使用し、自動インクリメントに設定す...
最近、問題のある新しい SQL が本番データベースに入力される数を最小限に抑えるために、開発仕様を整...
導入分散システムでは、分散ロックは最も基本的なツール クラスです。たとえば、支払い機能を備えた 2 ...
最近、会社初のミニプログラムの開発に参加しました。開発経験は基本的にWebViewをベースとしたハイ...
目次1. 手ぶれ補正2. スロットリング3. まとめ序文:フロントエンド開発者には、次の 2 つの要...
JSX を使用してコンポーネント システムを構築する前に、例を使用してコンポーネントの実装原理とロ...
1. 要件の説明Divタグの右上隅に削除アイコンを表示します2. 実装html、CSS 3. 参照コ...
1. 基礎知識: HTTP ヘッダー ユーザーエージェントユーザー エージェントは、ユーザー エージ...
データベースバージョン: mysql> select version(); +--------...
質問Nginx リバース プロキシの後、Tomcat アプリケーションは、クライアント ブラウザーの...
目次序文VueUseとは使いやすいおなじみの手ぶれ補正やスロットル機能もありますグローバル状態を共有...
今日 テーブル名から * を選択します。ここで、to_days(時間フィールド名) = to_day...
MySQL レプリケーションの詳細な説明と簡単な例マスタースレーブレプリケーション技術は、MySQL...