我有一个抛出 IOException 的方法,该方法是从 java 计时器 run() 调用的。由于 run() 不返回任何已检查的异常,并且我使用 AspectJ 进行日志记录,因此如何在spectj 中记录异常?
这是我的代码:
timer = new Timer();
`
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
for (OidTypes oidType : typesList) {
try {
valueIncrementOperation(oidType);//------this method throws exception
} catch (IOException e) {
System.out.println("Error occured inside Timer : "
+ e.getMessage());
timer.cancel();
timer = null;
}
}
` 我现在被迫使用 try/catch 。我有什么选择?
最佳答案
首先,您需要将 IOException 打包为未经检查的异常,真正的异常将是您在通知中捕获的异常的原因。
最简单的是获取 RuntimeException。
public void doTimerJob() {
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
throw new IOException("file not found");
} catch (IOException e) {
timer.cancel();
throw new RuntimeException(e);
}
}
}, new Date(), 2000);
}
那么您可以尝试以下操作:
为 TimerTask#run 创建切入点
pointcut timerTaskRun() : execution(public * java.util.TimerTask.run(..) );
以及抛出 RuntimeException 后的建议
after() throwing(RuntimeExceptione) : timerTaskRun() {
System.out.println("log and rethrow " + e.getCause().getMessage());
}
这将在记录异常后重新抛出异常。
如果你想记录并吞掉异常,你可以写一个环绕建议
Object around() : timerTaskRun() {
Object o;
try {
o = proceed();
} catch(RuntimeException e) {
System.out.println("log and swallow " + e.getCause().getMessage());
o = null;
}
return o;
}
请注意,您应该只有一个建议,after throwing
或 around
,而不是两者兼而有之。
但是您可能不想建议所有 TimerTask#run
调用以及所有 RuntimeException
。在这种情况下,您应该创建自己的类型,并在切入点和建议中使用它们。
“未检查”IOException
public class IOExceptionUnchecked extends RuntimeException {
private static final long serialVersionUID = 1L;
public IOExceptionUnchecked(IOException e) {
super(e);
}
}
自定义定时器任务
public class MyTimerTask extends TimerTask {
Timer owner = null;
public MyTimerTask(Timer timer) {this.owner = timer;}
@Override
public void run() {
try {
throw new IOException("file not found");
} catch (IOException e) {
owner.cancel();
throw new IOExceptionUnchecked(e);
}
}
}
切点
pointcut timerTaskRun() : execution(public * com.example.MyTimerTask.run(..) );
抛出建议后:
after() throwing(IOExceptionUnchecked e) : timerTaskRun() {
System.out.println("log and rethrow " + e.getCause().getMessage());
}
或者周围的建议
Object around() : timerTaskRun() {
Object o;
try {
o = proceed();
} catch(IOExceptionUnchecked e) {
System.out.println("log and swallow " + e.getCause().getMessage());
o = null;
}
return o;
}
关于java - 在java计时器中实现aspectj日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19965403/