This is a short tutorial that explains how to write an advice to change value of method arguments.
I have implemented a MutateArgsAspect which is applied on methods annotated with @MutateArgs
The advice converts the string argument passed to the annotated method from "BEFORE" to "AFTER"
Steps 1: Implement the annotation
-------------------------------------
package com.waseem.foundation;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
@Retention(RUNTIME)
public @interface MutateArgs {
}
-------------------------------------
Steps 2: Implement the Aspect
-------------------------------------
package com.waseem.foundation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MutateArgsAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(MutateArgsAspect.class);
@Around("@annotation(MutateArgs) && execution(* *(..))")
public Object before(ProceedingJoinPoint pjp) throws Throwable {
LOGGER.debug(pjp.getSignature().toLongString());
Object[] args = pjp.getArgs();
for (int i = 0; i < args.length; i++) {
if ("BEFORE".equals(args[i])) {
LOGGER.info("args[{}] : {}", i, args[i]);
args[i] = "AFTER";
}
}
Object output = pjp.proceed(args);
return output;
}
}
Note the @Around annotation.
1- @annotation(MutateArgs) means the Aspect is applied on all the methods annotated with MutateArgs annotation
2- execution(* *(..)) means the execution of any method regardless of return or parameter types
-------------------------------------
Step 3: Apply annotation on the methods for the Advice to work.
Here is an example where this annotation is applied on an API method
@GET
@Path("/mutateInController")
@Produces(MediaType.APPLICATION_JSON)
@MutateArgs
public Response mutateArgsOfThisMethod(@QueryParam("name") String name) {
LOGGER.info("Name in Controller : {}", name);
return Response.ok(name).build();
}
Here is another example were this annotation is applied on another simple method
@MutateArgs
public String mutateArgsOfThisMethod(String name) {
LOGGER.info("Name in Manager : {}", name);
return name;
}