Ashish Aggarwal
Ashish Aggarwal

Reputation: 3026

Spring AOP change value of methods argument on around advice

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.

Upvotes: 20

Views: 20838

Answers (3)

Subin Chalil
Subin Chalil

Reputation: 3660

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.

Upvotes: 5

Ashish Aggarwal
Ashish Aggarwal

Reputation: 3026

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();
}

Upvotes: 5

reto
reto

Reputation: 10463

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

Upvotes: 15

Related Questions