AspectJ: параметр в pointcut

Я использую AspectJ, чтобы давать советы всем общедоступным методам, у которых есть аргумент выбранного класса. Я пробовал следующее:

pointcut permissionCheckMethods(Session sess) : 
    (execution(public * *(.., Session)) && args(*, sess));

Это прекрасно работает для методов с как минимум двумя аргументами:

public void delete(Object item, Session currentSession);

но он не работает с такими методами, как:

public List listAll(Session currentSession);

Как я могу изменить свой pointcut, чтобы рекомендовать выполнение обоих методов? Другими словами: я ожидал, что подстановочный знак «..» будет представлять «ноль или более аргументов», но похоже, что вместо этого он означает «один или несколько» ...

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
24 787
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Ну что ж ... Я обошел это с помощью этого мерзкого трюка. Все еще ждем, пока кто-нибудь появится с "официальным" определением 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. Меняя местами аргументы, вы также можете сопоставлять первый или единственный. Но я не знаю, возможно ли сопоставление произвольной позиции.

соответствие любой произвольной позиции невозможно.

Timur Milovanov 03.10.2017 23:47

Я не могу расширить синтаксис 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, вы должны отметить это как Решение вашей проблемы. Чтобы другие не отвлекались от другой работы

Iomanip 08.02.2018 20:19
@Before(value = "execution(public * *(.., org.springframework.data.domain.Pageable , ..))")
private void isMethodPageable () {
    log.info("in a Aspect point cut isPageableParameterAvailable()");
}

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