[SPRING] Spring AOP를 사용하여 메소드 인수를 얻으시겠습니까?
SPRINGSpring AOP를 사용하여 메소드 인수를 얻으시겠습니까?
나는 Spring AOP를 사용하고 있고 aspect를 가지고있다 :
@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("******");
}
}
위 aspect는 addCustomer 메소드 실행을 차단합니다. addCustomer 메소드는 문자열을 입력으로 사용합니다. 하지만 logBefore 메서드 안에 addCustomer 메서드에 전달 된 입력을 기록해야합니다. 그렇게 할 수 있습니까?
해결법
-
==============================
1.몇 가지 옵션이 있습니다.
몇 가지 옵션이 있습니다.
먼저, 권고 된 메소드의 모든 인수를 포함하는 Object []를 리턴하는 JoinPoint # getArgs () 메소드를 사용할 수 있습니다. 당신이 그들과 함께하고 싶은 것에 따라 약간의 캐스팅을해야 할 수도 있습니다.
둘째, 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)
-
==============================
2.예, getArgs를 사용하여 인수 값을 찾을 수 있습니다.
예, 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); ... } }
-
==============================
3.많은 조언을 위해 하나의 pointcut을 정의하면 도움이 될 수있는 또 다른 방법이 있습니다 :
많은 조언을 위해 하나의 pointcut을 정의하면 도움이 될 수있는 또 다른 방법이 있습니다 :
@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()); }
-
==============================
4.귀하는 다음 방법 중 하나를 사용할 수 있습니다.
귀하는 다음 방법 중 하나를 사용할 수 있습니다.
@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 ()는 객체 배열을 반환합니다. 입력은 단일 문자열이기 때문에 하나의 객체 만 반환됩니다.
두 번째 접근법에서는 advice 메소드의 표현식과 입력 매개 변수에서 이름이 동일해야합니다. 즉 args (inputString) 및 public void logBefore2 (JoinPoint joinPoint, String inputString)
여기서 addCustomer (String)는 하나의 String 입력 매개 변수가있는 메소드를 나타냅니다.
-
==============================
5.단일 문자열 인수 인 경우 다음을 수행하십시오. joinPoint.getArgs () [0];
단일 문자열 인수 인 경우 다음을 수행하십시오. joinPoint.getArgs () [0];
-
==============================
6.모든 args를 기록해야하거나 메소드에 인수가 하나있는 경우 이전 대답에서 설명한 것처럼 getArgs를 간단히 사용할 수 있습니다.
모든 args를 기록해야하거나 메소드에 인수가 하나있는 경우 이전 대답에서 설명한 것처럼 getArgs를 간단히 사용할 수 있습니다.
특정 arg를 로그해야하는 경우이를 주석 처리하고 다음과 같이 값을 복구 할 수 있습니다.
@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 }
-
==============================
7.메소드 매개 변수와 해당 값을 가져올 수 있으며 다음 코드로 주석을 사용하여 주석을 추가 할 수 있습니다.
메소드 매개 변수와 해당 값을 가져올 수 있으며 다음 코드로 주석을 사용하여 주석을 추가 할 수 있습니다.
Map
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; }
from https://stackoverflow.com/questions/15660535/get-method-arguments-using-spring-aop by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Aspect aspect에 대한 스프링 autowired bean은 null이다. (0) | 2018.12.14 |
---|---|
[SPRING] 다중 스레드에서 스프링 트랜잭션을 사용하는 방법 (0) | 2018.12.14 |
[SPRING] XML 스키마 네임 스페이스 용 Spring NamespaceHandler를 찾을 수 없음 [http://www.springframework.org/schema/batch] (0) | 2018.12.14 |
[SPRING] Spring 부트가 서블릿 필터를 등록하지 못하게한다. (0) | 2018.12.14 |
[SPRING] IDE를 사용하여 스프링 부트 메인을 실행한다. (0) | 2018.12.14 |