Для 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 нельзя перегрузить?Следующее работает, когда порядок объявления 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, чтобы предотвратить это исключение.
Это баг, интересный случай. Спасибо за отчет!
Это не ошибка, но никогда не было реализовано. Если и получится, то по чистой случайности.
Хороший вопрос, простой ответ: он никогда не был реализован, потому что в лучшем случае это приятно, а в худшем может привести к путанице. См. также эту ветку списка рассылки за 2005 год и результирующую проблему Bugzilla #88620, которая так и не была реализована.
Ранжит, если вы создаете ошибки, пожалуйста, на GitHub, а не в старом экземпляре Bugzilla. Спасибо.
Конечно, Алекс, мы сделаем это в будущем. Спасибо за указатели
Зарегистрирована ошибка по этой проблеме: bugs.eclipse.org/bugs/show_bug.cgi?id=582496