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

标签 java spring-mvc timer aspectj aspect

我有一个抛出 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 throwingaround,而不是两者兼而有之。

但是您可能不想建议所有 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/

相关文章:

java - Spring Boot JdbcTemplate 过滤机制

java - 添加通配符以在调度程序 servlet 中映射 URI

android - 如何每 X 秒运行一次方法

ios - 在 iOS 中每秒更新一次 TableView 中单元格中标签的文本

java - Perl 使用 System.exit 从 Java Jar 返回代码

java - 在哪里放置gui项目代码

java - 是否可以使用不同的 View 解析器?

Javadoc @return 标记注释重复是否必要?

java - BlackBerry - 如何通过包含自定义管理器的 VerticalFieldManager 改进此搜索功能

python - Python 中的定时器