Получить аргументы метода с помощью Spring AOP?

Я использую Spring AOP и имею следующий аспект:

@Aspect public class LoggingAspect { @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("logBefore() is running!"); System.out.println("hijacked : " + joinPoint.getSignature().getName()); System.out.println("******"); } } 

addCustomer аспект перехватывает addCustomer метода addCustomer . Метод addCustomer принимает строку как входной. Но мне нужно регистрировать ввод, переданный методу logBefore внутри метода logBefore .
Можно ли это сделать?

У вас есть несколько вариантов:

Во-первых, вы можете использовать метод JoinPoint#getArgs() который возвращает Object[] содержащий все аргументы рекомендуемого метода. Возможно, вам придется делать кастинг в зависимости от того, что вы хотите с ними делать.

Во-вторых, вы можете использовать выражение pointcut args следующим образом:

 // use '..' in the args expression if you have zero or more parameters at that point @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..)) && args(yourString,..)") 

то ваш метод может быть определен как

 public void logBefore(JoinPoint joinPoint, String yourString) 

Да, значение любого аргумента можно найти с помощью getArgs

 @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))") public void logBefore(JoinPoint joinPoint) { Object[] signatureArgs = thisJoinPoint.getArgs(); for (Object signatureArg: signatureArgs) { System.out.println("Arg: " + signatureArg); ... } } 

Существует и другой способ, если вы определите один pointcut для многих советов, это может быть полезно:

 @Pointcut("execution(@com.stackoverflow.MyAnnotation * *(..))") protected void myPointcut() { } @AfterThrowing(pointcut = "myPointcut() && args(someId,..)", throwing = "e") public void afterThrowingException(JoinPoint joinPoint, Exception e, Integer someId) { System.out.println(someId.toString()); } @AfterReturning(pointcut = "myPointcut() && args(someId,..)") public void afterSuccessfulReturn(JoinPoint joinPoint, Integer someId) { System.out.println(someId.toString()); } 

Вы можете использовать один из следующих способов.

 @Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String))") public void logBefore1(JoinPoint joinPoint) { System.out.println(joinPoint.getArgs()[0]); } 

или

 @Before("execution(* ong.customer.bo.CustomerBo.addCustomer(String)), && args(inputString)") public void logBefore2(JoinPoint joinPoint, String inputString) { System.out.println(inputString); } 

joinpoint.getArgs () возвращает массив объектов. Так как ввод – одна строка, возвращается только один объект.

Во втором подходе имя должно быть одинаковым в выражении и параметре ввода в методе консультаций, т.е. args(inputString) и public void logBefore2(JoinPoint joinPoint, String inputString)

Здесь addCustomer(String) указывает метод с одним входным параметром String.

Если вам нужно зарегистрировать все аргументы или ваш метод имеет один аргумент, вы можете просто использовать getArgs, как описано в предыдущих ответах.

Если вам нужно зарегистрировать определенный аргумент arg, вы можете записать его, а затем восстановить его значение следующим образом:

 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Data { String methodName() default ""; } @Aspect public class YourAspect { @Around("...") public Object around(ProceedingJoinPoint point) throws Throwable { Method method = MethodSignature.class.cast(point.getSignature()).getMethod(); Object[] args = point.getArgs(); StringBuilder data = new StringBuilder(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (int argIndex = 0; argIndex < args.length; argIndex++) { for (Annotation paramAnnotation : parameterAnnotations[argIndex]) { if (!(paramAnnotation instanceof Data)) { continue; } Data dataAnnotation = (Data) paramAnnotation; if (dataAnnotation.methodName().length() > 0) { Object obj = args[argIndex]; Method dataMethod = obj.getClass().getMethod(dataAnnotation.methodName()); data.append(dataMethod.invoke(obj)); continue; } data.append(args[argIndex]); } } } } 

Примеры использования:

 public void doSomething(String someValue, @Data String someData, String otherValue) { // Apsect will log value of someData param } public void doSomething(String someValue, @Data(methodName = "id") SomeObject someData, String otherValue) { // Apsect will log returned value of someData.id() method } 

Если это единственный аргумент String, выполните: joinPoint.getArgs()[0];

вы можете получить параметр метода и его значение и аннотировать аннотацию следующим кодом:

Map annotatedParameterValue = getAnnotatedParameterValue(MethodSignature.class.cast(jp.getSignature()).getMethod(), jp.getArgs()); ….

 private Map getAnnotatedParameterValue(Method method, Object[] args) { Map annotatedParameters = new HashMap<>(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Parameter[] parameters = method.getParameters(); int i = 0; for (Annotation[] annotations : parameterAnnotations) { Object arg = args[i]; String name = parameters[i++].getDeclaringExecutable().getName(); for (Annotation annotation : annotations) { if (annotation instanceof AuditExpose) { annotatedParameters.put(name, arg); } } } return annotatedParameters; } 
  • Не удается найти дескриптор библиотеки тегов springframework
  • Установить системное свойство с конфигурационным файлом Spring
  • Как вы глобально настроили jacksonа игнорировать неизвестные свойства в течение весны?
  • Доступ к весенним бобам из сервлета в JBoss
  • Spring - вставка зависимости в ServletContextListener
  • Почему DispatcherServlet создает другой контекст приложения?
  • @Autowired bean имеет значение null при ссылке в конструкторе другого компонента
  • несколько пакетов в контексте: компонентное сканирование, настройка пружины
  • Вам нужна транзакция базы данных для чтения данных?
  • Выполнить метод при запуске весной
  • Весна: стандартная форма ведения журнала (перехватчик)
  • Давайте будем гением компьютера.