【问题标题】:How to inject a logging statement before every catch block in java如何在java中的每个catch块之前注入一个日志语句
【发布时间】:2015-06-14 02:50:42
【问题描述】:

我最初是使用 JBoss 开始使用面向方面编程的,并且已经实现了他们的代码注入 - 在方法被调用之前和之后以及在方法引发异常之后。 现在我想知道我们如何在方法中注入代码?我想在每个 catch 块执行之前注入一个 Logging 语句,我们如何使用 java 来做到这一点?

【问题讨论】:

  • 你可以使用像ASMJavassist这样的字节码操作库。
  • 我不确定 jboss 但在 java 中你只需添加代码,这几乎是根据定义。这就是 catch 块的全部目的
  • @Typo 不,他问的是面向方面的编程,它会自动做这样的事情。如果您的意思是“您如何使用 Java 做到这一点?A:您没有。”嗯,没错,但这是一个刻薄的答案。
  • @Elliot 感谢您的快速回复,我面临的问题是我有一个已经工作的代码,我不应该更改它。此代码生成并抛出异常,并在内部处理它们而无需任何日志记录,因此我需要注入日志记录语句!知道我需要从哪里开始吗?
  • @KausthubNaarayan 你不能“注入”日志语句;你能做的最接近的就是修改你的catch块中的字节码......不要指望它很容易。

标签: java jboss code-injection aop


【解决方案1】:

我对 JBoss AOP 了解不多,但无论如何您都可以使用 AspectJ,因为它具有 handler() 切入点。

驱动程序应用:

package de.scrum_master.app;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeoutException;

import javax.naming.NamingException;

public class Application {
    public static void throwRandomException() throws TimeoutException, IOException, NamingException {
        switch (new Random().nextInt(5)) {
            case 0: throw new TimeoutException("too late, baby");
            case 1: throw new FileNotFoundException("file.txt");
            case 2: throw new IOException("no read permission");
            case 3: throw new NullPointerException("cannot call method on non-existent object");
            case 4: throw new NamingException("unknown name");
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            try { throwRandomException(); }
            catch (NullPointerException e) {}
            catch (FileNotFoundException e) {}
            catch (TimeoutException e) {}
            catch (IOException e) {}
            catch (NamingException e) {}
        }
    }
}

方面:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class CaughtExceptionLogger {
    @Before("handler(*) && args(e)")
    public void logCaughtException(JoinPoint thisJoinPoint, Exception e) {
        System.out.println(thisJoinPoint + " -> " + e.getMessage());
    }
}

控制台输出:

handler(catch(TimeoutException)) -> too late, baby
handler(catch(FileNotFoundException)) -> file.txt
handler(catch(NamingException)) -> unknown name
handler(catch(TimeoutException)) -> too late, baby
handler(catch(NamingException)) -> unknown name
handler(catch(NamingException)) -> unknown name
handler(catch(NullPointerException)) -> cannot call method on non-existent object
handler(catch(FileNotFoundException)) -> file.txt
handler(catch(FileNotFoundException)) -> file.txt
handler(catch(NullPointerException)) -> cannot call method on non-existent object

【讨论】:

  • 感谢 kriegaex ,这正是我想做的!
  • 在我的示例中它不起作用,是否还有其他配置需求。
  • @Zigri2612:我不能对你的问题说任何聪明的事,没有看到你的代码。 “我的例子不起作用”并不是一个特别好的诊断依据。准备一个SSCCE 并在这里提出一个新问题怎么样?
  • @kriegaex 感谢您的回答,我们能否在特定的方法声明中也有这样的方面?例如,如果我在 throwRandomException() 方法中有一个 System.out.println(),并且我希望在其调用时触发一个方面。
  • 是的,但这是一个完全不同的话题。所以请不要劫持这个问题,而是(a)首先搜索您的问题(这里应该已经回答了多次),或者,如果(a)失败,创建一个新问题(在这种情况下应该没有必要)。 P.S.:cflow() 是你的朋友。 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多