在 Spring AOP 中使用 @AfterReturning 修改类的值

გენ*_*აძე 2 java spring spring-aop

如何使用@AfterReturning建议修改值,它适用于除字符串之外的任何对象。我知道字符串是不可变的。以及如何在不更改 AccountDAO 类中 saveEverything() 函数的返回类型的情况下修改字符串?这是代码片段:

@Component
public class AccountDAO {
    public String saveEverything(){
        String save = "save";
        return save;
    }
}
Run Code Online (Sandbox Code Playgroud)

和方面:

@Aspect
@Component
public class AfterAdviceAspect {
    @AfterReturning(pointcut = "execution(* *.save*())", returning = "save")
    public void afterReturn(JoinPoint joinPoint, Object save){
        save = "0";
        System.out.println("Done");
    }
}
Run Code Online (Sandbox Code Playgroud)

和主要应用程序:

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

R.G*_*R.G 6

来自文档:返回建议后

请注意,在返回建议后使用时,不可能返回完全不同的参考。

正如anavaras lamurep在评论中正确指出的那样,@Around可以使用建议来实现您的要求。一个示例方面如下

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,问题中给出的切入点表达式是全局的。该表达式将匹配对任何saveObject. 这可能会产生不希望的结果。建议将课程范围限制为建议。

- - 更新 - -

正如 @kriegaex 所指出的,为了更好的可读性和可维护性,切入点表达式可以重写为

execution(* com.package..*.save*())
Run Code Online (Sandbox Code Playgroud)

或者

execution(* save*()) && within(com.package..*)
Run Code Online (Sandbox Code Playgroud)