7

Spring 3.x、Java 6 を使用しています。

次のジョインポイントを持つ @Around アスペクトがあります。

@Around("execution(public * my.service.*.*Connector.*(..))")

したがって、私は基本的に、クラス名が「Connector」で終わるクラスのパブリック メソッドへのすべての呼び出しをインターセプトすることに関心があります。ここまでは順調ですね。

さて、私の観点では、メソッドの実際の引数名にアクセスしたいと思います:

public doStuff(String myarg, Long anotherArg)

myarganotherArg

私はそれを使用して理解しています:

CodeSignature signature = (CodeSignature)jointPoint.getSignature();
return signature.getParameterNames();

実際には動作しますが、" -g " フラグ (完全なデバッグ) を指定してコードをコンパイルし、実行したくない場合に限ります。

その種のランタイム情報にアクセスする他の方法はありますか?

ありがとうL

4

4 に答える 4

8

残念ながら、これを行うことはできません :-(。これは JVM/バイトコードのよく知られた制限です。(メソッド/クラス名とは対照的に)常にバイトコードに格納されるとは限らないため、リフレクションを使用して引数名を取得することはできません。 .

回避策として、いくつかのフレームワーク/仕様では、WebParam(nameプロパティ) やPathParam.

今のところ、注釈なしで取得できるのは値の配列だけです。

于 2011-02-17T15:18:58.197 に答える
4

の実装を確認してくださいorg.springframework.core.ParameterNameDiscoverer

no が設定されている場合、Spring で使用されるような注釈@RequestParamはパラメーター名を検査しますvalue。したがって@RequestParam String foo、実際には「foo」という名前のリクエストパラメーターを取得します。ParameterNameDiscoverer仕組みを利用しています。どの実装が使用されているかわかりません。それぞれを試してみてください。

はをLocalVariableTableParameterNameDiscoverer読み取り、.classasm を使用して名前を調べます。

だから、それは可能です。ただし、この情報は必ずキャッシュしてください (たとえば、キー = クラス + メソッド + パラメータ インデックスを使用して、パラメータ名をマップに保存します)。

ただし、ドキュメントに記載されているように、デバッグ情報が必要です。のドキュメントから@PathVariable

メソッド パラメーター名と URI テンプレート変数名の一致は、コードがデバッグを有効にしてコンパイルされている場合にのみ実行できます。デバッグを有効にしていない場合は、変数名の解決された値をメソッド パラメーターにバインドするために、@PathVariable アノテーションで URI テンプレート変数名の名前を指定する必要があります。

したがって、その情報を本当に含めたくない場合は、Tomasz Nurkiewicz の回答で回避策が説明されています。

于 2011-02-17T15:31:37.250 に答える
3

Java 8 には、追加のメタデータをバイト コードで格納できるようにする新しいコンパイラ フラグがあり、これらのパラメーター名は、リフレクションで Parameter オブジェクトを使用して抽出できます。JDK 8仕様を参照してください。hibernate org.springframework.core.ParameterNameDiscoverer の新しいバージョンでは、この機能を使用します。javac使用するには、次のフラグを使用してコンパイルします。

-parameters                Generate metadata for reflection on method parameters

リフレクションのParameterクラスを使用してパラメーターにアクセスします。

于 2014-09-10T00:39:00.030 に答える