围绕建议并继续调用:aspectJ,它是如何工作的?
around advice and proceed call: aspectJ, how it works?
我一直在努力弄清楚 around
建议 在 AspectJ
.
中的作用
不像之前和建议之后那么简单。有人可以简要介绍一下 around
建议的作用,以及 proceed
关键字的目的是什么吗?
非常非正式地,around
建议拦截给定的连接点,并且可以注入 新行为 before, after, and instead of that joinpoint。 proceed
是一个特殊的 特征 允许 around
建议 继续执行 joinpoint
.
来自 AspectJ 支持的 advice 类型(即, before
、after
和 around
), around
advice 是唯一允许 return 一个值 and/or 使用 proceed
。这使得 around
advice 可以多次执行相同的 joinpoint,或者根本不执行。此外,您甚至可以使用不同的上下文执行拦截的 joinpoint(例如,更改方法参数的值)。可以找到更多详细信息 here.
让我们以一些代码为例。想象一个名为 Rectangle
:
的 class
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; }
}
以及调用 class 的方法:
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
那么让我们一步一步地尝试理解输出结果,好吗?!。第一个advice会拦截classRectangle
中对方法public void Rectangle.setWidth(double)
的调用。并且会:
- 在该方法调用之前添加语句
System.out.println("Before setting width");
;
- 执行joinpoint两次(即调用方法
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
advice 将拦截对方法 public double Rectangle.getHeight()
的调用,在这些方法调用之前和之后注入语句 System.out.println("Before getting Height");
和 System.out.println("After getting Height");
。此外,会将 200
添加到 getHeight
编辑的值 return 中。因此,
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
工作原理的一个小例子,并不意味着您应该复制本示例中所做的相同操作,并且没有准确显示 编织 过程是如何在幕后发生的。
我一直在努力弄清楚 around
建议 在 AspectJ
.
不像之前和建议之后那么简单。有人可以简要介绍一下 around
建议的作用,以及 proceed
关键字的目的是什么吗?
非常非正式地,around
建议拦截给定的连接点,并且可以注入 新行为 before, after, and instead of that joinpoint。 proceed
是一个特殊的 特征 允许 around
建议 继续执行 joinpoint
.
来自 AspectJ 支持的 advice 类型(即, before
、after
和 around
), around
advice 是唯一允许 return 一个值 and/or 使用 proceed
。这使得 around
advice 可以多次执行相同的 joinpoint,或者根本不执行。此外,您甚至可以使用不同的上下文执行拦截的 joinpoint(例如,更改方法参数的值)。可以找到更多详细信息 here.
让我们以一些代码为例。想象一个名为 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; }
}
以及调用 class 的方法:
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
那么让我们一步一步地尝试理解输出结果,好吗?!。第一个advice会拦截classRectangle
中对方法public void Rectangle.setWidth(double)
的调用。并且会:
- 在该方法调用之前添加语句
System.out.println("Before setting width");
; - 执行joinpoint两次(即调用方法
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
advice 将拦截对方法 public double Rectangle.getHeight()
的调用,在这些方法调用之前和之后注入语句 System.out.println("Before getting Height");
和 System.out.println("After getting Height");
。此外,会将 200
添加到 getHeight
编辑的值 return 中。因此,
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
工作原理的一个小例子,并不意味着您应该复制本示例中所做的相同操作,并且没有准确显示 编织 过程是如何在幕后发生的。