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()");
}
Другие вопросы по тегам