복붙노트

[SPRING] 모든 위치에서 AspectJ pointcut 표현식 매개 변수 주석을 일치시킵니다.

SPRING

모든 위치에서 AspectJ pointcut 표현식 매개 변수 주석을 일치시킵니다.

특정 위치에 관계없이 특정 주석으로 주석 된 매개 변수를 포함하는 메서드를 일치하도록 pointcut 식을 정의하려고합니다. 제 경우에는 @Constraint 주석을 찾고 있습니다. 예 :

일치하는 방법 :

public void method1(@Constraint Car car)

public void method2(String id, @Constraint Plane plane)

public void method3(Wheel wheel, @Constraint List<Train> trains, @Constraint Plane plane)

public void method4(Motor motor, @Constraint Set<Train> trains, Bicycle bike, Wheel wheel)

public void method5(Wing wing, Motorcycle moto, @Constraint Truck truck, Bicycle bike, Wheel wheel)

지금까지 행운이없는 다음 표현식을 시도했습니다.

@Before("execution(public * *.*(..)) and @args(com.example.Constraint)") // there can be only one parameter
@Before("execution(public * *.*(..)) and @args(..,com.example.Constraint)") // parameter must be in last position
@Before("execution(public * *.*(..)) and @args(com.example.Constraint,..)") // parameter must be in first position
@Before("execution(public * *.*(..)) and (@args(com.example.Constraint,..) or @args(..,com.example.Constraint))") // parameter must be in first or last position, nothing in between
@Before("execution(public * *.*(..)) and @args(..,com.example.Constraint,..)") // Invalid

누군가가 올바른 해결책을 제시 할 수 있습니까? 그것은 가능한가?

해결법

  1. ==============================

    1.AspectJ에서는 args ()를 통해 임의의 위치에 인수를 바인딩 할 수 없으므로 모호함이 발생할 수 있습니다. 같은 유형의 두 개 이상의 매개 변수가 있다고 상상해보십시오 (이 경우 동일한 주석 유형으로 주석 처리 됨). 어느 쪽이 명명 된 args () 매개 변수에 바인딩되어야합니까? 그러면서

    AspectJ에서는 args ()를 통해 임의의 위치에 인수를 바인딩 할 수 없으므로 모호함이 발생할 수 있습니다. 같은 유형의 두 개 이상의 매개 변수가 있다고 상상해보십시오 (이 경우 동일한 주석 유형으로 주석 처리 됨). 어느 쪽이 명명 된 args () 매개 변수에 바인딩되어야합니까? 그러면서

    execution(public * *(.., @Deprecated (*), ..))
    

    독립 실행 형 표현식 (별 주위의 괄호에주의하십시오)으로 사용할 수 있습니다. args ()와 함께 사용할 수 없습니다. 따라서 메소드 실행 자체를 가로 채고 싶지 않고 주어진 애노테이션으로 첫 번째 또는 모든 매개 변수를 찾으면 다른 기사에서 보여준 것과 똑같이해야합니다. 나는 일종의 반복적 인 일이지만 응답을 다시 삭제할 수 없도록하기 위해서이다.

    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Constraint {}
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    public class Application {
        public void method1(@Constraint int i) {}
        public void method2(String id, @Constraint float f) {}
        public void method3(int i, @Constraint List<String> strings, @Constraint String s) {}
        public void method4(int i, @Constraint Set<Integer> numbers, float f, boolean b) {}
        public void method5(boolean b, String s, @Constraint String s2, float f, int i) {}
        public void notIntercepted(boolean b, String s, String s2, float f, int i) {}
    
        public static void main(String[] args) {
            List<String> strings = new ArrayList<String>();
            strings.add("foo");
            strings.add("bar");
            Set<Integer> numbers = new HashSet<Integer>();
            numbers.add(11);
            numbers.add(22);
            numbers.add(33);
    
            Application app = new Application();
            app.method1(1);
            app.method2("foo", 1f);
            app.method3(1, strings, "foo");
            app.method4(1, numbers, 1f, true);
            app.method5(false, "foo", "bar", 1f, 1);
            app.notIntercepted(false, "foo", "bar", 1f, 1);
        }
    }
    
    import java.lang.annotation.Annotation;
    
    import org.aspectj.lang.SoftException;
    import org.aspectj.lang.reflect.MethodSignature;
    
    public aspect ArgCatcherAspect {
        before() : execution(public * *(.., @Constraint (*), ..)) {
            System.out.println(thisJoinPointStaticPart);
            MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
            String methodName = signature.getMethod().getName();
            Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
            Annotation[][] annotations;
            try {
                annotations = thisJoinPoint.getTarget().getClass().
                    getMethod(methodName, parameterTypes).getParameterAnnotations();
            } catch (Exception e) {
                throw new SoftException(e);
            }
            int i = 0;
            for (Object arg : thisJoinPoint.getArgs()) {
                for (Annotation annotation : annotations[i]) {
                    if (annotation.annotationType() == Constraint.class)
                        System.out.println("  " + annotation + " -> " + arg);
                }
                i++;
            }
        }
    }
    

    보시다시피, 주어진 매개 변수의 주석을 선언 된 형식 이외의 것으로 가져 오는 것은 다소 까다 롭지 만 기본적으로 이전 게시물과 동일한 방식으로 작동합니다. 즉 인수 목록을 반복하는 방식으로 작동합니다.

  2. ==============================

    2.나는 당신이 실행 (public * *. * (.., @ com.example.Constraint *, ..)을 원한다고 생각한다.

    나는 당신이 실행 (public * *. * (.., @ com.example.Constraint *, ..)을 원한다고 생각한다.

  3. from https://stackoverflow.com/questions/11765996/aspectj-pointcut-expression-match-parameter-annotations-at-any-position by cc-by-sa and MIT license