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 |