Перед выполнением совета дважды… та же точка соединения указана дважды для одного и того же метода, поэтому он вызывается дважды

1

Мы применяем "до" рекомендации с использованием пользовательских аннотаций, чтобы выполнять только определенные методы, если применяется бизнес-логика (неинтересная для этой проблемы).

Мы видим, что этот аспект называется дважды для каждого вызова метода.

Отладка в нем я вижу, Cglib2AopProxy$CglibMethodInvocation.proceed имеет массив, называемый: interceptorsAndDynamicMethodMatchers. Этот массив перечисляет наш PointCut ("RequiresX") дважды.

Вот точка соединения:

@Before(@annotation(requiresX)")
public Object process(ProceedingJoinPoint joinPoint, RequiresACL requiresX) throws Throwable
{
    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
    log.info(" method:" + method.getName());

    // do business logic of the aspect…

    log.info(" joinPoint.proceed with call to " + method.getName());
 }

и вот наша пользовательская аннотация

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.Method)
public @interface RequiresX {
}

и вот метод, который мы можем перехватить:

@RequiresX()
public String someMethod() {    
    ....
}

Это кажется довольно ванильным, но я ясно сделал что-то не так. Любые предложения о том, как выполнять только один раз за звонок, будут очень признательны.

Теги:
aop
aspectj
aspect

2 ответа

1
Лучший ответ

Мы нашли ответ как путем проб и ошибок, так и через эту должность: http://forum.spring.io/forum/spring-projects/aop/25729-advice-is-called-twice-with-aop-auto-proxy- конфигурация

Итог: мы имели аннотацию @Aspect в классе аспект, а также указывали аспект в файле Spring. Не делай того и другого.

2

вы должны напечатать Pointcut и увидеть проблему как:

@Before(@annotation(requiresX)")
public Object process(ProceedingJoinPoint joinPoint, RequiresACL requiresX) throws Throwable
{

    log.info(" pointcut:" + joinPoint.getKind());
    // do business logic of the aspect…


 }

он напечатает проблему как:

pointcut:method-call 
pointcut:method-execution

Итак, вы должны изменить Pointcut как:

@Before(@annotation(RequiresX) && execution(@RequiresX * *.*(..)))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню