Я использую AspectJ, чтобы давать советы всем общедоступным методам, у которых есть аргумент выбранного класса. Я пробовал следующее:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session)) && args(*, sess));
Это прекрасно работает для методов с как минимум двумя аргументами:
public void delete(Object item, Session currentSession);
но он не работает с такими методами, как:
public List listAll(Session currentSession);
Как я могу изменить свой pointcut, чтобы рекомендовать выполнение обоих методов? Другими словами: я ожидал, что подстановочный знак «..» будет представлять «ноль или более аргументов», но похоже, что вместо этого он означает «один или несколько» ...





Ну что ж ... Я обошел это с помощью этого мерзкого трюка. Все еще ждем, пока кто-нибудь появится с "официальным" определением pointcut.
pointcut permissionCheckMethods(EhealthSession eheSess) :
(execution(public * *(.., EhealthSession)) && args(*, eheSess))
&& !within(it.___.security.PermissionsCheck);
pointcut permissionCheckMethods2(EhealthSession eheSess) :
(execution(public * *(EhealthSession)) && args(eheSess))
&& !within(it.___.security.PermissionsCheck)
&& !within(it.___.app.impl.EhealthApplicationImpl);
before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods(eheSess)
{
Signature sig = thisJoinPointStaticPart.getSignature();
check(eheSess, sig);
}
before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods2(eheSess)
{
Signature sig = thisJoinPointStaticPart.getSignature();
check(eheSess, sig);
}
Как насчет:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(..)) && args(.., sess));
Я предполагаю, что это будет соответствовать, если последний (или единственный) аргумент имеет тип Session. Меняя местами аргументы, вы также можете сопоставлять первый или единственный. Но я не знаю, возможно ли сопоставление произвольной позиции.
Я не могу расширить синтаксис AspectJ за вас, но могу предложить обходной путь. Но сначала позвольте мне объяснить, почему невозможно сделать то, что вы хотите, с определением args в pointcut: потому что, если вы сопоставите свой параметр EhealthSession в любом месте в сигнатуре метода, как AspectJ должен обрабатывать случай, когда сигнатура содержит несколько параметров этот класс? Значение eheSess было бы неоднозначным.
Теперь обходной путь: это может быть медленнее - насколько сильно зависит от вашей среды, просто проверьте это - но вы можете просто настроить pointcut, чтобы сопоставить все потенциальные методы независимо от их списка параметров, а затем позволить совету найти нужный вам параметр, проверив параметр. список:
pointcut permissionCheckMethods() : execution(public * *(..));
before() throws AuthorizationException : permissionCheckMethods() {
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof EhealthSession)
check(arg, thisJoinPointStaticPart.getSignature());
}
}
P.S .: Возможно, вы сможете сузить фокус с помощью within(SomeBaseClass+), within(*Postfix) или within(com.company.package..*), чтобы не применять совет ко всей вселенной.
Вы должны использовать .. (двойные точки) в конце и начале следующим образом:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session , ..)) );
Также избавьтесь от && args(*, sess), потому что это означает, что вы ожидаете поймать только те методы с любым типом для первого параметра, но sess в качестве второго параметра и не более 2 параметров.
@Manrico Corazzi, вы должны отметить это как Решение вашей проблемы. Чтобы другие не отвлекались от другой работы
@Before(value = "execution(public * *(.., org.springframework.data.domain.Pageable , ..))")
private void isMethodPageable () {
log.info("in a Aspect point cut isPageableParameterAvailable()");
}
соответствие любой произвольной позиции невозможно.