我一直在尝试找出around
建议的用处AspectJ
。
这不像之前和之后的建议那样简单。有人可以简要介绍一下around
建议的用途以及proceed
关键字的目的吗?
非常非正式的around
咨询截取一个给定的连接点,并能注入新的行为前,后,和而不是该连接点。本proceed
是一个特殊的功能,允许around
建议继续的执行joinpoint
。
从的类型的建议通过的AspectJ支持(即 before
,after
和around
),该around
建议是唯一一个允许返回的值和/或使用proceed
。这样一来,around
建议就可以多次执行相同的联接点,或者根本不执行该联接点。此外,你甚至可以在不同的上下文中执行拦截的连接点(例如,更改方法参数的值)。可以在这里找到更多详细信息。
让我们以一些代码为例。想象一下一个名为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");
在该方法的调用之前添加语句;setWidth
),将其原始参数从修改w
为w + 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)
statement代替对方法的调用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
工作原理的一小部分说明,并不意味着你应该重复此示例中所做的操作,并且不能准确地显示机织过程是如何进行的。