How to modify value with @AfterReturning advice, it works for any object except String. I know that String is Immutability. and how to modify the string without changing returning type of saveEverything() function in AccountDAO class? here are code snippet:
@Component
public class AccountDAO {
public String saveEverything(){
String save = "save";
return save;
}
}
and aspect:
@Aspect
@Component
public class AfterAdviceAspect {
@AfterReturning(pointcut = "execution(* *.save*())", returning = "save")
public void afterReturn(JoinPoint joinPoint, Object save){
save = "0";
System.out.println("Done");
}
}
and main app:
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(JavaConfiguration.class);
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
System.out.println(">"+accountDAO.saveEverything());;
context.close();
}
}
From the documentation :After Returning Advice
Please note that it is not possible to return a totally different reference when using after returning advice.
As anavaras lamurep rightly pointed out in the comments , @Around
advice can be used to achieve your requirement. An example aspect would be as follows
@Aspect
@Component
public class ExampleAspect {
@Around("execution(* com.package..*.save*()) && within(com.package..*)")
public String around(ProceedingJoinPoint pjp) throws Throwable {
String rtnValue = null;
try {
// get the return value;
rtnValue = (String) pjp.proceed();
} catch(Exception e) {
// log or re-throw the exception
}
// modify the return value
rtnValue = "0";
return rtnValue;
}
}
Please note that the pointcut expression given in the question is global . This expression will match call to any spring bean method starting with save
and returning an Object
. This might have undesired outcome. It is recommended to limit the scope of classes to advice.
--- Update ---
As pointed out by @kriegaex , for better readability and maintainability the pointcut expression may be rewritten as either
execution(* com.package..*.save*())
or
execution(* save*()) && within(com.package..*)