Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java计时器中实现aspectj日志记录_Java_Spring Mvc_Timer_Aspectj_Aspect - Fatal编程技术网

在java计时器中实现aspectj日志记录

在java计时器中实现aspectj日志记录,java,spring-mvc,timer,aspectj,aspect,Java,Spring Mvc,Timer,Aspectj,Aspect,我有一个抛出IOException的方法,该方法是从java计时器run()调用的。由于run()不返回任何已检查的异常,并且我正在使用AspectJ进行日志记录,因此如何在AspectJ中记录异常 这是我的代码: timer=新定时器() ` ` 我现在被迫使用try/catch。我的选项是什么?您无法摆脱try/catch块,因为IOException是一个选中的异常,并且TimerTask#run声明不会抛出任何选中的异常。此外,catch块中还有用于取消计时器的附加逻辑 您能做的最接近的

我有一个抛出IOException的方法,该方法是从java计时器run()调用的。由于run()不返回任何已检查的异常,并且我正在使用AspectJ进行日志记录,因此如何在AspectJ中记录异常

这是我的代码:

timer=新定时器()
`

`
我现在被迫使用try/catch。我的选项是什么?

您无法摆脱try/catch块,因为
IOException
是一个选中的异常,并且
TimerTask#run
声明不会抛出任何选中的异常。此外,catch块中还有用于取消计时器的附加逻辑

您能做的最接近的事情是将
IOException
包装成
RuntimeException
并重新抛出它

   catch(IOException){
        timer.cancel();
        throw new RuntimeException(e);
    }
即使这样做,AspectJ也不会记录异常和堆栈跟踪。
为此,您需要使用一个容器(如Spring)来创建
TimerTask
实例,并用AspectJ拦截器将其包装。

您无法摆脱try/catch块,因为
IOException
是一个选中的异常,并且
TimerTask#run
被声明为不抛出任何选中的异常。此外,catch块中还有用于取消计时器的附加逻辑

您能做的最接近的事情是将
IOException
包装成
RuntimeException
并重新抛出它

   catch(IOException){
        timer.cancel();
        throw new RuntimeException(e);
    }
即使这样做,AspectJ也不会记录异常和堆栈跟踪。
为此,您需要使用容器(如Spring)创建
TimerTask
实例,并用AspectJ拦截器将其包装。

首先,您需要将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创建一个切入点

以及引发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;
}
Object around() : timerTaskRun() {
    Object o;
    try {
        o = proceed();   
    } catch(IOExceptionUnchecked e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}
请注意,您应该只有一个建议,在抛出后
或周围
而不是两者都有

但您可能不想建议所有
TimerTask#运行
调用以及所有
RuntimeException
s。在这种情况下,您应该创建自己的类型,在切入点和建议中使用这些类型

“未检查”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(RuntimeException e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}
Object around() : timerTaskRun() {
    Object o;
    try {
        o = proceed();   
    } catch(IOExceptionUnchecked e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}

首先,您需要将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创建一个切入点

以及引发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;
}
Object around() : timerTaskRun() {
    Object o;
    try {
        o = proceed();   
    } catch(IOExceptionUnchecked e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}
请注意,您应该只有一个建议,在抛出后
或周围
而不是两者都有

但您可能不想建议所有
TimerTask#运行
调用以及所有
RuntimeException
s。在这种情况下,您应该创建自己的类型,在切入点和建议中使用这些类型

“未检查”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(RuntimeException e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}
Object around() : timerTaskRun() {
    Object o;
    try {
        o = proceed();   
    } catch(IOExceptionUnchecked e) {
        System.out.println("log and swallow " + e.getCause().getMessage());
        o = null;
    }
    return o;
}

尝试调用e.getCause()@PeterQuiring:我正在尝试摆脱try/catch块,既然aspectj无法拦截运行(),那么我从哪里调用它呢?尝试调用e.getCause()@PeterQuiring:我正在尝试摆脱try/catch块,既然aspectj无法拦截运行(),那么我从哪里调用它呢。谢谢你的评论,我正在使用Spring MVC。如何用aspectj包装
TimerTask
实例?有几个步骤:1)将匿名类移动到一级类。2) 使用spring管理bean,通过注释或将其放入spring上下文文件中,请注意,您可能需要使用
prototype
scope。3) 应用aspectj相关注释谢谢你的评论,我正在使用SpringMVC。如何用aspectj包装
TimerTask
实例?有几个步骤:1)将匿名类移动到一级类。2) 使用spring管理bean,通过注释或将其放入spring上下文文件中,请注意,您可能需要使用
prototype
scope。3) 应用aspectj相关注释非常感谢兄弟。。感谢您花时间和精力发布代码并检查所有细节…我一定会尝试实现它…再次感谢…@decentguy不客气!希望它能帮助你找到解决问题的方法!非常感谢你,兄弟。。感谢您花时间和精力发布代码并检查所有细节…我一定会尝试实现它…再次感谢…@decentguy不客气!希望它能帮助你找到解决问题的方法!