AspectJ: параметр в pointcut
Я использую AspectJ, чтобы советовать всем открытым методам, которые имеют аргументы выбранного класса. Я попробовал следующее:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session)) && args(*, sess));
Это прекрасно работает для методов как минимум с 2 аргументами:
public void delete(Object item, Session currentSession);
но он не работает с такими методами, как:
public List listAll(Session currentSession);
Как я могу изменить свой pointcut, чтобы рекомендовать оба метода выполнения? Другими словами: я ожидал, что подстановочный знак ".." будет представлять "ноль или более аргументов", но похоже, что он означает вместо "один или несколько"...
4 ответа
О, хорошо... Я работал над этим с этим противным трюком. Все еще жду, когда кто-нибудь появится с "официальным" определением точки.
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. Меняя местами положения аргументов, вы также можете сопоставить первый или единственный. Но я не знаю, возможно ли сопоставление любой произвольной позиции.
Вы должны использовать.. (двойные точки) в конце и начале следующим образом:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session , ..)) );
Также избавиться от && args(*, sess)
потому что это означает, что вы ожидаете поймать только те методы с любым типом для первого параметра, но sess
в качестве второго параметра и не более 2-х параметров..
Я не могу расширить синтаксис AspectJ для вас, но могу предложить обходной путь. Но сначала позвольте мне объяснить, почему невозможно сделать то, что вы хотите с args
определение в pointcut: потому что если бы вы соответствовали EhealthSession
параметр anyplace в сигнатуре метода, как AspectJ должен обрабатывать случай, когда сигнатура содержит несколько параметров этого класса? Значение eheSess
было бы неоднозначно.
Теперь обходной путь: он может быть медленнее - насколько это зависит от вашей среды, просто протестируйте его - но вы можете просто сделать так, чтобы pointcut соответствовал всем потенциальным методам независимо от их списка параметров, а затем позволить совету найти нужный параметр, проверив его. список:
pointcut permissionCheckMethods() : execution(public * *(..));
before() throws AuthorizationException : permissionCheckMethods() {
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof EhealthSession)
check(arg, thisJoinPointStaticPart.getSignature());
}
}
PS: Может быть, вы можете сузить фокус с помощью within(SomeBaseClass+)
или же within(*Postfix)
или же within(com.company.package..*)
чтобы не применять этот совет ко всей вселенной.
@Before(value = "execution(public * *(.., org.springframework.data.domain.Pageable , ..))")
private void isMethodPageable () {
log.info("in a Aspect point cut isPageableParameterAvailable()");
}