2014-11-12 6 views
1

Я определил класс для операций CRUD для комментариев. Метод чтения перегружен.spring AoP, выражение pointcut для перегруженных методов с одинаковыми параметрами

class Comment{ 
    // method 1: returns all the comments by a user 
    findAll(long userId, long subjectId, String param); 

    // method 2: returns all the comments of all the users 
    findAll(long subjectId, String param) 
} 

Выражение точки разреза Я попытался это

@Around("execution(* com.package..*Controller.findAll(..)) && args(userId,subjectId,..)") 
public Object validateFindAll(final ProceedingJoinPoint proceedingJoinPoint, final long userId, final long subjectId) { 
    // validate userId, if available 
    // validate subjectId 
} 

Проблема: Поскольку типы данных ID_пользователя и subjectId такие же, выражение точки, когда применяется к методу 2 сдвигает значения Param на 1 место. Это означает, что выражение не понимает, что первый параметр userId не передается. Вместо этого userId получает значение «subjectId» в качестве значения, а subjectId получает смежный параметр «param» в качестве значения.

Примечание

  1. Я пытаюсь избежать написания другой метод, как findUserComments().

  2. Я хочу поддерживать согласованность в приложении. Существуют и другие классы с похожими шаблонами операций CRUD.

Вопрос: Можно ли определить выражение, применимое к обоим методам с первым параметром является идентификатор пользователя необязательным?

EDIT - Решение Пока я играл с различными подходами, предложенными в качестве решений, приведенных ниже, я, наконец, удален метод 2. Я обрабатывать этот случай в методе 1.

ответ

0

Проблема связана с методом averloading на самом деле. Поскольку вы проходите длинный userId, и long subjectId AOP всегда будет пытаться сопоставить эти аргументы. Решения могут быть

1) Создайте еще один pointcut для других аргументов i.e.-Долго, долго и другие долго, String

2) Использование переменного аргумента подписи в начале, такие как

@Around("execution(* com.org..findAll(..)) && args(..,subjectId,param)") 
public Object validateFindAll(final ProceedingJoinPoint joinPoint, final long userId, final long subjectId) { 

} 

вместо использования переменного аргумента в начале. Затем вы можете использовать метод getArgs() для определения аргументов. Это простое решение, но может замедлить вашу обработку.

3) Хотя в качестве проблемы с дизайном я предлагаю инкапсулировать все ваши параметры в один объект и передать его. Вместо передачи нескольких параметров. Это поможет вам и в будущем.

+0

Спасибо! создал еще один pointcut. –

2

Вы не можете явно привязать AspectJ, а затем ожидать, что он будет соответствовать несовместимой сигнатуре. Таким образом, ваш pointcut будет соответствовать только findAll(long, long, ..), т. Е. «Метод 1» в вашем примере. Вы можете указать необязательные аргументы с .., но тогда вы не можете привязать их к именованным параметрам.

Например, можно сопоставить оба метода и привязать long subjectId и String param через args(.., subjectId, param), потому что оба параметра предсказуемо выровнены по правому краю в конце подписи. Если вы хотите какой-либо дополнительный (и, таким образом, несвязанного) параметр, вам нужно использовать thisJoinPoint.getArgs():

@Around("execution(* com.package..*Controller.findAll(..)) && args(.., subjectId, param)") 
public Object validateFindAll(
    final ProceedingJoinPoint thisJoinPoint, 
    final long subjectId, 
    final String param 
) { 
    if (thisJoinPoint.getArgs().length == 3) 
     System.out.println(thisJoinPoint + " -> " + thisJoinPoint.getArgs()[0] + ", " + subjectId + ", " + param); 
    else 
     System.out.println(thisJoinPoint + " -> " + subjectId + ", " + param); 
    // (...) 
} 

Но пока getArgs() динамична, это, вероятно, медленнее, чем параметр связывания, поскольку он использует отражение. Может быть, с двумя точками не так уж и плохо. Если ваш метод подсказок делает сложные вещи до/после proceed(), вы все равно можете учитывать эти вещи в вспомогательных методах и называть их обоими советами.

+0

Спасибо! getArgs() был полезен. –

+0

Тогда почему вы не принимаете мой ответ вместо другого? – kriegaex

Смежные вопросы