JAVA問題レコード-Spring AOPを使用して特定のメソッドの注釈をブロックし、ビジネスに基づいて注釈フィールド値を変更します.
3085 ワード
問題の原因:
まずブロックトラフィックがあり、埋め込みコンテンツを追加する必要があるが、ここで埋め込みポイントはパラメータ値にフィールド値があり、このフィールド値の違いは、異なる打点情報(これはインタフェースが正しい場合に呼び出される)を送信し、元のトラフィックと埋め込みポイントをデカップリングする出発点に走り、注釈とSpringAOPを利用して実現することを選択する.実はこの実現には他の方法があります.しかし今回は私が実現した方法について説明し、出会った問題を記録します.
一言も言わないで,まずコードをつけなさい.
次にコードの一部を解く
1、釈@AfterReturningこれは、ビジネスの呼び出し結果に基づいて実行する必要があるかどうかを判断するため、メソッド実行が返された後に織り込まれています.
2、PointResource pointResource = methodSignature.getMethod().getAnnotation(PointResource.class);この文はメソッド上のコメントクラス、InvocationHandler handler=Proxyを取得します.getInvocationHandler(pointResource);この文はエージェントを利用して注釈クラスを取得するInvocationHandlerであるが,注釈クラスに対応する具体的なInvocationHandlerインタフェース実装クラスはAnnotationInvocationHandlerであるが,このクラスはpublicではないので直接使用することができず,具体的な実装クラスを知ると,AnnotationInvocationHandlerのソースクラスから、すべての注釈クラスのフィールドがMapmemberValuesというフィールドに維持されていることがわかります.sourceField=handlerです.getClass().getDeclaredField("memberValues");この文を実行すると、Map memberValuesフィールドが取得され、memberValuesを通過する.put("source", 7);このような類似の文は、注釈を制御するフィールド値の内容を実現する.
ここまでのすべての業務の実現はすでに完成して、次に出会った穴について話します.....
=======================================================
ピット点記述:現在のクラスはSpringによって管理されているため、クラスのデフォルトのオブジェクトインスタンスが単一のクラスである場合、クラスメソッドに追加された注釈クラスも単一のクラスである(注釈クラスの記述は適切ではないかもしれないが、メソッドが呼び出されるたびに同じ注釈クラスであることを表すため)、では、プロキシモードで注釈クラスのフィールド値を変更した後、そのフィールド値への影響は永続的です.しかし、この注釈クラスがプロトタイプであると勘違いしていました(つまり、アクセスするたびに新しい注釈クラスとみなされます).これにより、ビジネスコードの書き込みが間違ってしまいました.
まずブロックトラフィックがあり、埋め込みコンテンツを追加する必要があるが、ここで埋め込みポイントはパラメータ値にフィールド値があり、このフィールド値の違いは、異なる打点情報(これはインタフェースが正しい場合に呼び出される)を送信し、元のトラフィックと埋め込みポイントをデカップリングする出発点に走り、注釈とSpringAOPを利用して実現することを選択する.実はこの実現には他の方法があります.しかし今回は私が実現した方法について説明し、出会った問題を記録します.
一言も言わないで,まずコードをつけなさい.
@AfterReturning(value = "interceptorMethod(reqModel,request)", returning = "responseModel")
public void afterReturningAdvice(JoinPoint joinPoint, ReqPublishDynamicModelXX reqModel, HttpServletRequest request, ResponseModel responseModel) {
if (responseModel.getError() == ErrorCodes.OK){
Signature signature = joinPoint.getSignature();
if (signature instanceof MethodSignature) {
MethodSignature methodSignature = (MethodSignature) signature;
PointResource pointResource = methodSignature.getMethod().getAnnotation(PointResource.class);
if (null != pointResource) {
InvocationHandler handler = Proxy.getInvocationHandler(pointResource);
Field sourceField;
try {
sourceField = handler.getClass().getDeclaredField("memberValues");
sourceField.setAccessible(true);
Map memberValues = (Map) sourceField.get(handler);
if (reqModel.getTopicId() <= 0) {
memberValues.put("source", 7);
} else {
memberValues.put("source", 5);
}
} catch (Exception e) {
// .....
}
userPointService.handleUserPointResource(userModel.getUid(), pointResource.source(), pointResource.type(), pointResource.plus(), UUID.randomUUID().toString());
}
}
}
}
次にコードの一部を解く
1、釈@AfterReturningこれは、ビジネスの呼び出し結果に基づいて実行する必要があるかどうかを判断するため、メソッド実行が返された後に織り込まれています.
2、PointResource pointResource = methodSignature.getMethod().getAnnotation(PointResource.class);この文はメソッド上のコメントクラス、InvocationHandler handler=Proxyを取得します.getInvocationHandler(pointResource);この文はエージェントを利用して注釈クラスを取得するInvocationHandlerであるが,注釈クラスに対応する具体的なInvocationHandlerインタフェース実装クラスはAnnotationInvocationHandlerであるが,このクラスはpublicではないので直接使用することができず,具体的な実装クラスを知ると,AnnotationInvocationHandlerのソースクラスから、すべての注釈クラスのフィールドがMapmemberValuesというフィールドに維持されていることがわかります.sourceField=handlerです.getClass().getDeclaredField("memberValues");この文を実行すると、Map memberValuesフィールドが取得され、memberValuesを通過する.put("source", 7);このような類似の文は、注釈を制御するフィールド値の内容を実現する.
ここまでのすべての業務の実現はすでに完成して、次に出会った穴について話します.....
=======================================================
ピット点記述:現在のクラスはSpringによって管理されているため、クラスのデフォルトのオブジェクトインスタンスが単一のクラスである場合、クラスメソッドに追加された注釈クラスも単一のクラスである(注釈クラスの記述は適切ではないかもしれないが、メソッドが呼び出されるたびに同じ注釈クラスであることを表すため)、では、プロキシモードで注釈クラスのフィールド値を変更した後、そのフィールド値への影響は永続的です.しかし、この注釈クラスがプロトタイプであると勘違いしていました(つまり、アクセスするたびに新しい注釈クラスとみなされます).これにより、ビジネスコードの書き込みが間違ってしまいました.