around建议并继续调用:aspectj,它是如何工作的?

a64a0gku  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(399)

我一直在想 around 忠告是有用的 AspectJ .
它不像之前和之后的建议那样简单。有人能简单介绍一下 around 建议是有用的,那么建议的目的是什么呢 proceed 关键字?

kuhbmx9i

kuhbmx9i1#

非常非正式地说 around advice截获给定的joinpoint,并可以在joinpoint之前、之后和之后注入新行为,而不是该joinpoint。这个 proceed 是允许 around 建议继续执行 joinpoint .
从aspectj支持的通知类型(即。, before , after ,和 around ),的 around 通知是唯一允许返回值和/或使用 proceed . 这就使得 around 建议多次执行同一连接点,或根本不执行。此外,您甚至可以使用不同的上下文执行截获的joinpoint(例如,更改方法参数的值)。更多细节可以在这里找到。
让我们用一些代码作为例子。想象一个名为 Rectangle :

public class Rectangle {
    private double width, height;

    public void setWidth(double w) {
           System.out.println("Set Width " + w);
           this.width = w;
    }

    public void setHeight(double h) {
           System.out.println("Set height " + h);
           this.height = h;
    }

    public double getWidth() {return this.width;}
    public double getHeight() {return this.height; }
}

调用该类的方法:

public class Main {

    public static void main(String[] args) {
        Rectangle s = new Rectangle();
        s.setWidth(10);
        s.setHeight(2);
        double w =  s.getWidth();
        double h = s.getHeight()
        System.out.println("Width " + w + " Height " + h);
    }
}

如果运行上述代码,将得到以下输出:

Set Width 10.0
Set Height 2.0
Width 10.0 Height 2.0

不过,让我们补充一些 around 混合建议:

void around(double w) : call(public void  Rectangle.setWidth(double)) && args(w){
      System.out.println("Before setting width");
      proceed(w + 100);
      proceed(w + 100);
      System.out.println("After setting width");
 }

 double around() : call(public double  Rectangle.getHeight()){
        System.out.println("Before getting Height");
        double h = proceed();
        System.out.println("After getting Height");
        return h + 200;
 }

 void around(double w) : call(public void  Rectangle.setHeight(double)) && args(w){
        System.out.println("No Height setting");
  }

现在您将得到输出:

Before setting width
Set Width 110.0
Set Width 110.0
After setting width
No Height setting
Before getting Height
After getting Height
Width 110.0 Height 200.0

所以让我们试着一步一步地理解这个输出,好吗?!。第一个通知将拦截对方法的调用 public void Rectangle.setWidth(double) 在班上 Rectangle . 并将:
添加语句 System.out.println("Before setting width"); 在调用该方法之前;
执行joinpoint两次(即调用方法 setWidth 两次),修改其原始参数 ww + 100 ;
添加语句 System.out.println("After setting width"); 在调用该方法之后。
因此,原始代码现在相当于:

public class Main {

    public static void main(String[] args) {
        Rectangle s = new Rectangle();
        System.out.println("Before setting width");  // <--- new lines
        s.setWidth(10+100);
        s.setWidth(10+100);
        System.out.println("After setting width");   // <--- new lines
        s.setHeight(2);
        double w =  s.getWidth();
        double h = s.getHeight()
        System.out.println("Width " + w + " Height " + h);
    }
}

第二个 around 通知将拦截对方法的调用 public double Rectangle.getHeight() ,在这些方法调用语句之前和之后注入 System.out.println("Before getting Height"); 以及 System.out.println("After getting Height"); 分别是。此外,将添加 200 返回的值 getHeight . 因此,

public class Main {

    public static void main(String[] args) {
        Rectangle s = new Rectangle();
        System.out.println("Before setting width"); 
        s.setWidth(10+100);
        s.setWidth(10+100);
        System.out.println("After setting width");  
        s.setHeight(2);
        double w =  s.getWidth();
        System.out.println("Before getting Height"); // <-- new lines
        double h = s.getHeight() + 200 // <-- new behaviour 
        System.out.println("After getting Height"); // <-- new lines
        System.out.println("Width " + w + " Height " + h); 

    }
}

最后,第三个 around 通知将替换对方法的调用 public void Rectangle.setHeight(double) 根据声明 System.out.println("No Height setting"); . 因此:

public class Main {

    public static void main(String[] args) {
        Rectangle s = new Rectangle();
        System.out.println("Before setting width"); 
        s.setWidth(10+100);
        s.setWidth(10+100);
        System.out.println("After setting width");
        System.out.println("No Height setting"); // <-- new line  
        double w =  s.getWidth();
        System.out.println("Before getting Height");
        double h = s.getHeight() + 200 // <-- new behaviour 
        System.out.println("After getting Height");
        System.out.println("Width " + w + " Height " + h); 

    }
}

这只是一个小小的例子,说明了 around 工作,并不意味着你应该复制相同的在这个例子中所做的,并没有准确地显示如何编织过程发生在引擎盖下。

相关问题