Spring AOP를 사용하여 메소드 인수를 얻습니까?
나는 Spring AOP를 사용하고 있으며 다음과 같은 측면이 있습니다.
@Aspect
public class LoggingAspect {
    @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }
}
 
위의 측면은 addCustomer메서드 실행을 가로 챕니다 . addCustomer메소드는 문자열을 입력으로 사용합니다. 하지만 addCustomer메서드 내부 logBefore메서드에 전달 된 입력을 기록해야합니다 . 
그렇게 할 수 있습니까?
몇 가지 옵션이 있습니다.
먼저, 권고 된 메서드의 모든 인수를 포함 JoinPoint#getArgs()하는를 반환하는 메서드를 사용할 수 있습니다 Object[]. 당신이 그들과 함께하고 싶은 것에 따라 약간의 캐스팅을해야 할 수도 있습니다.
둘째, 다음 args과 같이 pointcut 표현식을 사용할 수 있습니다 .
// use '..' in the args expression if you have zero or more parameters at that point
@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..)) && args(yourString,..)")
 
그러면 귀하의 방법은
public void logBefore(JoinPoint joinPoint, String yourString) 
예, 모든 인수의 값은 getArgs를 사용하여 찾을 수 있습니다.
@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
public void logBefore(JoinPoint joinPoint) {
   Object[] signatureArgs = thisJoinPoint.getArgs();
   for (Object signatureArg: signatureArgs) {
      System.out.println("Arg: " + signatureArg);
      ...
   }
}
모든 인수를 기록해야하거나 메서드에 하나의 인수가있는 경우 이전 답변에서 설명한대로 간단히 getArgs를 사용할 수 있습니다.
특정 인수를 기록해야하는 경우 주석을 달고 다음과 같이 값을 복구 할 수 있습니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Data {
 String methodName() default "";
}
@Aspect
public class YourAspect {
 @Around("...")
 public Object around(ProceedingJoinPoint point) throws Throwable {
  Method method = MethodSignature.class.cast(point.getSignature()).getMethod();
  Object[] args = point.getArgs();
  StringBuilder data = new StringBuilder();
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    for (int argIndex = 0; argIndex < args.length; argIndex++) {
        for (Annotation paramAnnotation : parameterAnnotations[argIndex]) {
            if (!(paramAnnotation instanceof Data)) {
                continue;
            }
            Data dataAnnotation = (Data) paramAnnotation;
            if (dataAnnotation.methodName().length() > 0) {
                Object obj = args[argIndex];
                Method dataMethod = obj.getClass().getMethod(dataAnnotation.methodName());
                data.append(dataMethod.invoke(obj));
                continue;
            }
            data.append(args[argIndex]);
        }
    }
 }
}
 
사용 예 :
public void doSomething(String someValue, @Data String someData, String otherValue) {
    // Apsect will log value of someData param
}
public void doSomething(String someValue, @Data(methodName = "id") SomeObject someData, String otherValue) {
    // Apsect will log returned value of someData.id() method
}
많은 조언에 대해 하나의 포인트 컷을 정의하면 도움이 될 수있는 또 다른 방법이 있습니다.
@Pointcut("execution(@com.stackoverflow.MyAnnotation * *(..))")
protected void myPointcut() {
}
@AfterThrowing(pointcut = "myPointcut() && args(someId,..)", throwing = "e")
public void afterThrowingException(JoinPoint joinPoint, Exception e, Integer someId) {
    System.out.println(someId.toString());
}
@AfterReturning(pointcut = "myPointcut() && args(someId,..)")
public void afterSuccessfulReturn(JoinPoint joinPoint, Integer someId) {
    System.out.println(someId.toString());
}
다음 방법 중 하나를 사용할 수 있습니다.
@Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String))")
public void logBefore1(JoinPoint joinPoint) {
    System.out.println(joinPoint.getArgs()[0]);
 }
 
또는
@Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String)), && args(inputString)")
public void logBefore2(JoinPoint joinPoint, String inputString) {
    System.out.println(inputString);
 }
 
joinpoint.getArgs ()는 객체 배열을 반환합니다. 입력은 단일 문자열이므로 하나의 객체 만 반환됩니다.
두 번째 방법에서, 이름이 통보 방법 즉 발현 입력 파라미터 동일해야 args(inputString)하고public void logBefore2(JoinPoint joinPoint, String inputString)
여기서는 addCustomer(String)하나의 문자열 입력 매개 변수가있는 메소드를 나타냅니다.
단일 문자열 인수 인 경우 다음을 수행하십시오. joinPoint.getArgs()[0];
메소드 매개 변수와 그 값을 얻을 수 있으며 다음 코드로 주석이 추가 된 경우 :
Map<String, Object> annotatedParameterValue = getAnnotatedParameterValue(MethodSignature.class.cast(jp.getSignature()).getMethod(), jp.getArgs());  ....
private Map<String, Object> getAnnotatedParameterValue(Method method, Object[] args) {
        Map<String, Object> annotatedParameters = new HashMap<>();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        Parameter[] parameters = method.getParameters();
        int i = 0;
        for (Annotation[] annotations : parameterAnnotations) {
            Object arg = args[i];
            String name = parameters[i++].getDeclaringExecutable().getName();
            for (Annotation annotation : annotations) {
                if (annotation instanceof AuditExpose) {
                    annotatedParameters.put(name, arg);
                }
            }
        }
        return annotatedParameters;
    }
ReferenceURL : https://stackoverflow.com/questions/15660535/get-method-arguments-using-spring-aop
'programing' 카테고리의 다른 글
| ^ (XOR) 연산자는 무엇을합니까? (0) | 2021.01.18 | 
|---|---|
| AngularJS 사용자 지정 공급자를 테스트하는 방법 (0) | 2021.01.18 | 
| Json.Net을 사용하여 JSON 배열 구문 분석 (0) | 2021.01.18 | 
| IIS : 확장자없이 파일을 제공하는 방법은 무엇입니까? (0) | 2021.01.18 | 
| launchMode =“singleTask”설정 대 활동 launchMode =“singleTop”설정 (0) | 2021.01.18 |