Почему метод имени @Pointcut нельзя перегрузить?

Для Spring Framework 6.0.11 об АОП, имея

public class CienciaPointcut {

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..))")
    public void cienciaServiceFinds() {

    }

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..)) " +
              "&& target(cienciaService) && this(proxy)")
    public void cienciaServiceFinds(CienciaService cienciaService, Object proxy) {

    }

}

Обратите внимание, что метод cienciaServiceFinds перегружен и последний используется как:

@AfterThrowing(pointcut = "com.manuel.jordan.aop.pointcut.CienciaPointcut.cienciaServiceFinds(cienciaService, proxy)", 
               throwing = "exception")

Когда приложение/тест выполняется, он завершается с ошибкой при запуске:

Caused by: java.lang.IllegalStateException: Required parameter names not available when parsing pointcut cienciaServiceFinds in type com.manuel.jordan.aop.pointcut.CienciaPointcut
    at org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate.getDeclaredPointcuts(Java15ReflectionBasedReferenceTypeDelegate.java:299)
    at org.aspectj.weaver.ReferenceType.getDeclaredPointcuts(ReferenceType.java:890)
    at org.aspectj.weaver.ResolvedType$PointcutGetter.get(ResolvedType.java:261)
    at org.aspectj.weaver.ResolvedType$PointcutGetter.get(ResolvedType.java:258)
    at org.aspectj.weaver.Iterators$4$1.hasNext(Iterators.java:213)
    at org.aspectj.weaver.Iterators$4.hasNext(Iterators.java:230)
    at org.aspectj.weaver.ResolvedType.findPointcut(ResolvedType.java:767)
    at org.aspectj.weaver.patterns.ReferencePointcut.resolveBindings(ReferencePointcut.java:148)
    at org.aspectj.weaver.patterns.Pointcut.resolve(Pointcut.java:189)
    at org.aspectj.weaver.tools.PointcutParser.resolvePointcutExpression(PointcutParser.java:331)
    at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:312)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:222)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.obtainPointcutExpression(AspectJExpressionPointcut.java:193)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:172)
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:226)
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:288)
    at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:320)

Но когда используется

public class CienciaPointcut {

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..))")
    public void cienciaServiceFinds() {

    }

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..)) " +
              "&& target(cienciaService) && this(proxy)")
    public void cienciaServiceFinds2P(CienciaService cienciaService, Object proxy) {

    }

}

Обратите внимание, что сейчас используются cienciaServiceFinds и cienciaServiceFinds2P. И, конечно же, используется как:

@AfterThrowing(pointcut = "com.manuel.jordan.aop.pointcut.CienciaPointcut.cienciaServiceFinds2P(cienciaService, proxy)", 
               throwing = "exception")

Когда приложение/тест выполняется, оно работает нормально.

Вопрос

  • Почему именованный метод @Pointcut нельзя перегрузить?
0
0
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Следующее работает, когда порядок объявления pointcut изменен.

public class CienciaPointcut {

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..)) " +
              "&& target(cienciaService) && this(proxy)")
    public void cienciaServiceFinds(CienciaService cienciaService, Object proxy) {

    }

    @Pointcut("execution(* com.manuel.jordan.service.CienciaService.find*(..))")
    public void cienciaServiceFinds() {

    }

}

Это не ответ, но я предполагаю, что, когда AspectJ встретил Advice для обработки, первое совпавшее имя pointcut не удовлетворило ожидание аргумента.

Здесь следует отметить, что речь идет не о перегрузке метода, а о порядке обработки pointcut.

Попытка использовать Spring-boot-версию: 2.6.4

Обновлять

При отладке проблема связана с методом tryToDiscoverParameterNames(), вызываемым из Java15ReflectionBasedReferenceTypeDelegate.getDeclaredPointcuts() где логика «пытается» обнаружить параметры.

pnames = tryToDiscoverParameterNames(pcs[i]);

Метод tryToDiscoverParameterNames() сравнивает только имена методов, чтобы получить имена параметров через Java15AnnotationFinder.getParameterNames(). Это приводит к неправильной идентификации метода pointcut, и нисходящая логика не может идентифицировать параметры, связанные с pointcut.

Насколько я понимаю, эта логика здесь ошибочна, и проверка условия должна также учитывать часть аргументов pointcut, чтобы предотвратить это исключение.

Зарегистрирована ошибка по этой проблеме: bugs.eclipse.org/bugs/show_bug.cgi?id=582496

R.G 30.09.2023 10:11

Это баг, интересный случай. Спасибо за отчет!

Manuel Jordan 30.09.2023 14:55

Это не ошибка, но никогда не было реализовано. Если и получится, то по чистой случайности.

kriegaex 04.10.2023 06:10

Хороший вопрос, простой ответ: он никогда не был реализован, потому что в лучшем случае это приятно, а в худшем может привести к путанице. См. также эту ветку списка рассылки за 2005 год и результирующую проблему Bugzilla #88620, которая так и не была реализована.

Ранжит, если вы создаете ошибки, пожалуйста, на GitHub, а не в старом экземпляре Bugzilla. Спасибо.

Конечно, Алекс, мы сделаем это в будущем. Спасибо за указатели

R.G 04.10.2023 06:18

Другие вопросы по теме