如何使用Aspectj捕获和抑制从Java类抛出的异常



我想使用Aspectj处理从Circle.getArea()方法抛出的这个异常。

Shape.java

package Shapes;

public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter(){
return 2 * Math.PI * this.radius;
}
public double getArea(){
return Math.PI * this.radius * this.radius;
}
}

矩形.java


package Shapes;

public class Rectangle {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getPerimeter() {
return 2 * (this.width + this.height);
}
public double getArea() {
return this.width * this.height;
}
}

Circle.java


package Shapes;

public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter() {
return 2 * Math.PI * this.radius;
}
public double getArea() {
throw new RuntimeException("Oops, I don't know how to calculate this :(");
}
}

Main.java


package Shapes;

public class Main {

public static void main(String[] args) {
try {
Shape s;
s = (Shape) new Rectangle(2, 10);
System.out.println("The area of " + s + " is " + s.getArea());

s = (Shape) new Rectangle(-2, 10);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());

s = (Shape) new Circle(-2);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());

s = (Shape) new Circle(2);
System.out.println("The area of " + s + " is " + s.getArea());
}
catch(Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}

Resolve.aj


package Shapes;

privileged public aspect Resolve {
declare parents: Rectangle implements Shape;
declare parents: Circle implements Shape;

public String Rectangle.getName(){
return "Rectangle";
}

public String Circle.getName(){
return "Circle";
}

public String Rectangle.toString(){
return this.getName()+"("+this.width+","+this.height+")";
}
public String Circle.toString(){
return this.getName()+"("+this.radius+")";
}


after() throwing(RuntimeException e) : execution(* Circle.*()){
handleException();
}   

protected void handleException()
{
System.out.println("Error detected");
}
}

当前输出为:

The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
Error: Oops, I don't know how to calculate this :(

我想避免打印";错误:哎呀,我不知道如何计算:(",我需要在最后得到圆对象的真实面积。但是,我不能更改任何.java文件。所有更改都应使用Resolve.aj文件。

您需要使用around建议,而不是后的

Object around () : execution(* Circle.*()){
try {
return proceed();
} 
catch(Exception e) 
{
handleException();
}
return null;
}   

代码输出:

The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
The area of Circle(2.0) is 0.0

为什么我们使用前后建议

非常非正式地,around建议拦截给定的连接点,并且可以在之前、之后以及而不是插入新行为proceed是一个特殊的功能,允许around建议继续执行joinpoint

根据AspectJ支持的建议的类型(,即beforeafteraround(,around是唯一允许返回值和/或使用proceed的建议。这使得around建议可以多次执行相同的连接点,或者根本不执行它。此外,您甚至可以使用不同的上下文执行截获的连接点(例如,更改方法参数的值(。

有关建议和继续操作的更多信息可以在这个SO线程上找到。

我们的around建议将拦截类Circle中方法的所有执行连接点,并相应地处理这些方法抛出的异常。

相关内容

  • 没有找到相关文章

最新更新