Хорошо, Шамсир, у меня просто есть немного свободного времени, поэтому я пытаюсь ответить на твой вопрос, а ты не отвечаешь на все мои вопросы из моих комментариев. Я делаю это следующим образом: я не использую имена параметров, а пытаюсь сопоставить параметры с аннотацией @RequestParam("accessToken")
, т.е. я буду сопоставлять тип аннотации и значение с магическим именем «accessToken», а не с именем параметра метода, которое может измениться из-за простого рефакторинга кем-то, кто не знает о вашем аспекте, из-за удаления отладочной информации из файла класса во время компиляции или из-за обфускации.
Вот некоторый самосогласованный пример кода, который был протестирован на AspectJ, а не на Spring AOP, но синтаксис последнего в любом случае является подмножеством синтаксиса первого:
Пример класса с основным методом:
Существует три метода, каждый из которых имеет аннотацию @RequestParam
для одного из параметров, но только два из них имеют магическое значение «accessToken». Они должны совпадать независимо от типа параметра (один String
и один int
), но параметр с @RequestParam("someParameter")
не должен совпадать. Строго говоря, все исполнения методов сопоставляются, но отражение во время выполнения устраняет нежелательные. Если ваши аннотации будут на уровне класса или метода или на типах параметров, мы могли бы сопоставить их непосредственно в pointcut без отражения, но в случае аннотаций параметров это выходит за рамки текущих возможностей AspectJ (v1.8.4), и мы должны использовать отражение , к несчастью.
package de.scrum_master.app;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
public class MyResponse {
public MyResponse saveUser(
@RequestParam("accessToken") String accessToken,
@RequestBody final UserDto userDto
) {
return this;
}
public MyResponse doSomething(
@RequestParam("someParameter") String text,
@RequestBody final UserDto userDto
) {
return this;
}
public MyResponse doSomethingElse(
@RequestParam("accessToken") int number
) {
return this;
}
public static void main(String[] args) {
MyResponse myResponse = new MyResponse();
myResponse.doSomething("I am not a token", new UserDto());
myResponse.saveUser("I am a token", new UserDto());
myResponse.doSomethingElse(12345);
}
}
Вспомогательный класс-пустышка для компиляции кода:
package de.scrum_master.app;
public class UserDto {}
Аспект:
Обратите внимание, что мой всеобъемлющий пункт execution(* *(..))
предназначен только для иллюстрации. Вы должны сузить его до методов, которые вам действительно нужны.
package de.scrum_master.aspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.bind.annotation.RequestParam;
@Aspect
public class AccessTokenAspect {
@Around("execution(* *(..))")
public Object handleAccessToken(ProceedingJoinPoint thisJoinPoint) throws Throwable {
System.out.println(thisJoinPoint);
Object[] args = thisJoinPoint.getArgs();
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
Method method = methodSignature.getMethod();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
assert args.length == parameterAnnotations.length;
for (int argIndex = 0; argIndex < args.length; argIndex++) {
for (Annotation annotation : parameterAnnotations[argIndex]) {
if (!(annotation instanceof RequestParam))
continue;
RequestParam requestParam = (RequestParam) annotation;
if (! "accessToken".equals(requestParam.value()))
continue;
System.out.println(" " + requestParam.value() + " = " + args[argIndex]);
}
}
return thisJoinPoint.proceed();
}
}
Вывод в консоль:
execution(void de.scrum_master.app.MyResponse.main(String[]))
execution(MyResponse de.scrum_master.app.MyResponse.doSomething(String, UserDto))
execution(MyResponse de.scrum_master.app.MyResponse.saveUser(String, UserDto))
accessToken = I am a token
execution(MyResponse de.scrum_master.app.MyResponse.doSomethingElse(int))
accessToken = 12345
См. также этот ответ на связанный, но несколько более простой вопрос с аналогичным кодом.
person
kriegaex
schedule
05.01.2015
getArgs()
или отражения. - person kriegaex   schedule 30.12.2014@RequestParameter
, а не имя переменной, которое может легко измениться и не кажется очень надежным. Волшебные имена параметров — плохая идея. - person kriegaex   schedule 05.01.2015