Modify value from class with @AfterReturning in Spring AOP

安稳与你 提交于 2021-02-05 09:21:17

问题


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

回答1:


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..*)


来源:https://stackoverflow.com/questions/61759409/modify-value-from-class-with-afterreturning-in-spring-aop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!