Spring AOP:如何将参数从被调用的方法传递给advice方法?

时间:2015-10-27 07:49:06

标签: java spring spring-aop

我正在设计一个系统,我需要将参数从被调用方法传递给advice方法。我提供了一个简单的代码来说明问题 -

// AOPMain.java:

public class AOPMain {

public static void main(String[] args) {
    ApplicationContext cxt = new ClassPathXmlApplicationContext("spring.xml");

    Employee emp = cxt.getBean("employee", Employee.class);

    emp.sayHello();
}

}

// Employee.java:

public class Employee {

private String name;

public String getName() {
    System.out.println("getName");
    return name;
}

public void setName(String name) {
    System.out.println("setName");
    this.name = name;
}

public void sayHello() {
    System.out.println("Hello World!");
    //How to pass argument to afterAdvice
}

}

// Logging.java:

 @Aspect
public class Logging {

    @Pointcut("execution(public void sayHello())") 
    public void doSomething(){}         

    @After("doSomething()")             
    public void afterAdvice() {
        System.out.println("After Advice");
        //Depending on the argument passed, send notification
    }
}

我如何设计这个系统?我知道有一些方法可以使用&& args()将参数传递给AOPMain本身的建议方法,但我无法找到针对此特定问题的任何示例代码。

我知道它违反了基本设计原则,建议方法没有松散耦合。那么Spring支持这个吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

@After("doSomething()")             
public void afterAdvice(JoinPoint joinPoint) {
   System.out.println("After Advice");
   //joinPoint.getArgs(); 
   //Depending on the argument passed, send notification
}

没有解决您的问题?请参阅get-method-arguments-using-spring-aop了解详情。

答案 1 :(得分:1)

有两种方法可以从建议的方法中获取信息:

  • 让它返回一个值并在建议中使用该返回值:

    public Arg sayHello() {
        System.out.println("Hello World!");
        //How to pass argument to afterAdvice
        Arg arg = ...;
        return arg;
    }
    
    @AfterReturning(pointcut="doSomething()", returning="retval")             
    public void afterAdvice(Object retval) {
        System.out.println("After Advice");
        // use retval here ...
    }
    
  • 使用JoinPoint访问调用方法的原始对象,并将arg作为对象属性传递:

    public void sayHello() {
        System.out.println("Hello World!");
        //How to pass argument to afterAdvice
        this.arg = ...;
    }
    
    @After("doSomething()")             
    public void afterAdvice(JoinPoint jp) {
        System.out.println("After Advice");
        Employee emp = (Employee) jp.getTarget();
        // use emp.arg here ...
    }
    

    如果建议的对象是有状态的,那么这只是有意义的 - 不要考虑在作为共享对象的服务或控制器上使用它......