20

Is it possible to change method argument value on basis of some check before executing using Spring AOP

My method

public String doSomething(final String someText, final boolean doTask) {
    // Some Content
    return "Some Text";
}

Advice method

public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
    String methodName = methodInvocation.getMethod().getName();

    Object[] arguments = methodInvocation.getArguments();
    if (arguments.length >= 2) {
        if (arguments[0] instanceof String) {
            String content = (String) arguments[0];
            if(content.equalsIgnoreCase("A")) {
                // Set my second argument as false
            } else {
                // Set my second argument as true
            }
        }
    }
    return methodInvocation.proceed();
}

Please suggest me the way to set the method argument value as there is no setter options for the argument.

Subin Chalil
  • 3,531
  • 2
  • 24
  • 38
Ashish Aggarwal
  • 3,018
  • 2
  • 23
  • 46

3 Answers3

14

Yes that's possible. You need a ProceedingJoinPoint and instead of:

methodInvocation.proceed();

you can then call proceed with the new arguments, for example:

methodInvocation.proceed(new Object[] {content, false});

see http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html#aop-ataspectj-advice-proceeding-with-the-call

reto
  • 9,995
  • 5
  • 53
  • 52
5

I got my answer using MethodInvocation

public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
    String methodName = methodInvocation.getMethod().getName();

    Object[] arguments = methodInvocation.getArguments();
    if (arguments.length >= 2) {
        if (arguments[0] instanceof String) {
            String content = (String) arguments[0];
            if(content.equalsIgnoreCase("A")) {
                if (methodInvocation instanceof ReflectiveMethodInvocation) {
                    ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) methodInvocation;
                    arguments[1] = false;
                    invocation.setArguments(arguments);
                }
            } else {
                if (methodInvocation instanceof ReflectiveMethodInvocation) {
                    ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) methodInvocation;
                    arguments[1] = true;
                    invocation.setArguments(arguments);
                }
            }
        }
    }
    return methodInvocation.proceed();
}
Ashish Aggarwal
  • 3,018
  • 2
  • 23
  • 46
5

You can use Spring AOP, create point cut using @Around. Then you can use the below code to change the arguments of the method, based on the condition.

int index = 0;
Object[] modifiedArgs = proceedingJoinPoint.getArgs();

for (Object arg : proceedingJoinPoint.getArgs()) {
    if (arg instanceof User) {    // Check on what basis argument have to be modified.
        modifiedArgs[index]=user;
       }
    index++;
}
return proceedingJoinPoint.proceed(modifiedArgs);  //Continue with the method with modified arguments.
Subin Chalil
  • 3,531
  • 2
  • 24
  • 38