Spring 4.3を使用しています。メソッドのパラメーター名とそれに渡される値を取得することは可能ですか?これは、AOP(アドバイス前)を使用して実行できると思います。可能であれば、ソースコードを教えてください。
以下は期待どおりに動作します(Java 8 + Spring 5.0.4 + AspectJ 1.8.13):
@Aspect
@Component
public class SomeAspect {
@Around("@annotation(SomeAnnotation)")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();
System.out.println("First parameter's name: " + codeSignature.getParameterNames()[0]);
System.out.println("First argument's value: " + joinPoint.getArgs()[0]);
return joinPoint.proceed();
}
}
CodeSignature methodSignature = (CodedSignature) joinPoint.getSignature();
String[] sigParamNames = codeSignature.getParameterNames();
メソッドシグネチャの引数名を取得できます。
残念ながら、これはできません。これはバイトコードのよく知られた制限です。引数名は常にバイトコードに格納されるわけではないため、リフレクションを使用して引数名を取得することはできません。
回避策として、@ParamName(name = "paramName")
などの注釈を追加できます。
そのため、次の方法でパラメーター名を取得できます。
MethodSignature.getMethod().getParameterAnnotations()
更新
Java 8なので、これを行うことができます
メソッドJava.lang.reflect.Executable.getParametersを使用して、メソッドまたはコンストラクターの仮パラメーターの名前を取得できます。 (クラスMethodとConstructorはクラスExecutableを拡張するため、メソッドExecutable.getParametersを継承します。)ただし、.classファイルは、デフォルトでは仮パラメーター名を格納しません。これは、クラスファイルを生成および使用する多くのツールが、パラメーター名を含む.classファイルの静的および動的フットプリントが大きくなることを期待しない可能性があるためです。特に、これらのツールはより大きな.classファイルを処理する必要があり、Java仮想マシン(JVM)はより多くのメモリを使用します。さらに、シークレットやパスワードなどの一部のパラメータ名は、機密性の高いメソッドに関する情報を公開します。
特定の.classファイルに仮パラメーター名を格納し、Reflection APIが仮パラメーター名を取得できるようにするには、javacコンパイラーに-parametersオプションを指定してソースファイルをコンパイルします。
https://docs.Oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html
AOPアドバイスでは、JoinPointのメソッドを使用して、メソッドとそのパラメーターにアクセスできます。オンラインおよびstackoverflowに複数の例があります。
メソッドの詳細を取得するには: https://docs.jboss.org/jbossaop/docs/2.0.0.GA/docs/aspect-framework/apidocs/org/jboss/aop/joinpoint/MethodInvocation.html#getMethod %28%29