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

Java 在Spring AOP中使用@AfterReturning修改类中的值,java,spring,spring-aop,Java,Spring,Spring Aop,如何使用@AfterReturning advice修改值,它适用于除字符串以外的任何对象。我知道字符串是不可变的。如何在不改变AccountDAO类中saveEverything函数的返回类型的情况下修改字符串? 以下是代码片段: @Component public class AccountDAO { public String saveEverything(){ String save = "save"; return save; } }

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

@Component
public class AccountDAO {
    public String saveEverything(){
        String save = "save";
        return save;
    }
}
和方面:

@Aspect
@Component
public class AfterAdviceAspect {
    @AfterReturning(pointcut = "execution(* *.save*())", returning = "save")
    public void afterReturn(JoinPoint joinPoint, Object save){
        save = "0";
        System.out.println("Done");
    }
}
和主应用程序:

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();
  }
}
从文件中:

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

正如阿纳瓦拉斯·拉穆雷普在评论中正确指出的那样,@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;
    }
}
请注意,问题中给出的切入点表达式是全局表达式。此表达式将匹配对任何以save开始并返回对象的springbean方法的调用。这可能会产生不期望的结果。建议将课程范围限制为建议

--更新--

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

execution(* com.package..*.save*())

从文件中:

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

正如阿纳瓦拉斯·拉穆雷普在评论中正确指出的那样,@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;
    }
}
请注意,问题中给出的切入点表达式是全局表达式。此表达式将匹配对任何以save开始并返回对象的springbean方法的调用。这可能会产生不期望的结果。建议将课程范围限制为建议

--更新--

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

execution(* com.package..*.save*())


你为什么想要实现这样的目标?您可以直接在右侧返回0。如果仍然需要,Joinpoint包含返回值,基于此,您可以执行一些操作。我想修改字符串,然后通过aspect将其传递给方法。您可以参考本文,您可以使用aspect并更改返回值。希望这对你有所帮助。你为什么想取得这样的成就?您可以直接在右侧返回0。如果仍然需要,Joinpoint包含返回值,基于此,您可以执行一些操作。我想修改字符串,然后通过aspect将其传递给方法。您可以参考本文,您可以使用aspect并更改返回值。希望这能有所帮助。对这个正确答案稍作改进的一种方法是通过执行*com.package..*.save*或执行*save*&&withincom.package..*,去掉多余的包名说明符:-这是我想问的。在阅读之后,我就开始这样写切入点表达式:一个写得好的切入点至少应该包括前两种类型kind和scoping。请让我知道,如果我需要将这个问题转化为一个SO问题,以便它能够造福于其他人?这是一个一般性的建议,因此当然是有意义的。作为一名程序员,我不喜欢的是冗余。如果重构包结构,在这种情况下,您必须在两个地方更新切入点——很容易忘记其中一个。此外,我发现较长的切入点更难阅读。如果你看我的第一个例子,它既有种类又有范围。第二个示例也是如此,但都没有冗余包名称。当然,这可能是个人偏好的问题,但我更喜欢我建议的变体,而不是你的。正如我之前所说,你的也是正确的。我将投票表决-对这个正确答案进行一点改进的一种方法是通过执行*com.package..*.save*或执行*save*&&withincom.package..*,去掉多余的包名说明符:-这是我想问的。在阅读之后,我就开始这样写切入点表达式:一个写得好的切入点至少应该包括前两种类型kind和scoping。请让我知道,如果我需要将这个问题转化为一个SO问题,以便它能够造福于其他人?这是一个一般性的建议,因此当然是有意义的。作为一名程序员,我不喜欢的是冗余。如果重构包结构,在这种情况下,您必须在两个地方更新切入点——很容易忘记其中一个。此外,我发现较长的切入点更难阅读。如果你看我的第一个例子,它既有种类又有范围。第二个示例也是如此,但都没有冗余包名称。当然,这可能是个人偏好的问题,但我更喜欢我建议的变体,而不是你的。正如我之前所说,你的也是正确的。我将投票表决-