2

这可能是一个非常愚蠢的问题,但是,有没有办法在 Java 中将某些内容打印到控制台并在其他地方监听时触发触发器?

我对触发器或 System 类(或就此而言的 Logger)知之甚少,所以如果有更简单的方法(没有触发器)请告诉我。

我们正在尝试使用 Logger 来记录我们所有的测试。目前,我们一直在使用简单的“System.out.println”来记录控制台中的所有内容,所以我想知道是否可以在打印到它时触发触发器,然后让侦听器将该信息添加到 Logger。

谢谢。

4

4 回答 4

8

最直接的方法是

System.setOut(new PrintStream(System.out) {
  public void println(String s) {
    logger.log(s);
    super.println(s);
  }
  // override some other methods?
});
于 2012-02-09T22:28:38.263 回答
3

面向方面的编程 (AOP) 可以帮助您实现这种行为。

由于您正在使用 Java,因此您可以使用 AspectJ(最成熟的 AOP 语言之一)来捕获System.out.println()对 Logger 类的所有调用并“注入”您的通知行为。

以下是 AspectJ 中的一些示例代码,说明它是如何工作的:

pointcut somethingIsBeingLogged(): execution(public static * System.out.println());
before() : somethingIsBeingLogged() {
    // Get the context by joinPoint.getThis();
    // Notify the Logger class
}

您实际上可以停止调用,System.out.println()只让您的 Logger 类进行控制。如果您想采用 AOP 路径,我可以提供更多详细信息。

于 2012-02-09T22:05:59.340 回答
2

这只是 Louis Wasserman 出色答案的一个很好的单例包装器。我的代码可供任何希望使用它的人免费使用。使用它,您可以以相当简单的方式在任何地方获得控制台输出。

public class SystemOutListener {

    private static SystemOutListener singleton;

    public static SystemOutListener GetSingleton() {
        if (singleton == null) {
            singleton = new SystemOutListener();
            singleton.ReplaceStandartSystemOutPrintStream();
        }
        return singleton;
    }
    private ArrayList<ISystemOutObserver> observersList = new ArrayList<>();

    public void AttachSystemOutObserver(ISystemOutObserver observer) {
        observersList.add(observer);
    }

    public void RemoveSystemOutObserver(ISystemOutObserver observer) {
        observersList.remove(observer);
    }

    private void FireSystemOutPrintln(String message) {
        for (int i = 0; i < observersList.size(); i++) {
            java.awt.EventQueue.invokeLater(new HandleSystemOutRunner(observersList.get(i), message));
        }
    }

    private void ReplaceStandartSystemOutPrintStream() {
        System.setOut(new PrintStream(System.out) {
            @Override
            public void println(String s) {
                super.println(s);
                FireSystemOutPrintln(s);
            }
        });
    }

    public interface ISystemOutObserver {
        public void HandleSystemOut(String message);
    }

    private class HandleSystemOutRunner implements Runnable {

        private String message;
        private ISystemOutObserver target;

        public HandleSystemOutRunner(ISystemOutObserver target, String message) {
            this.message = message;
            this.target = target;
        }

        @Override
        public void run() {
            target.HandleSystemOut(message);
        }
    }
}

用法:

SystemOutListener.GetSingleton().AttachSystemOutObserver(/*YOUR OBSERVER*/)

Lambdas(Java 8) 也可以用来代替观察者!

于 2013-05-29T08:41:35.103 回答
1

可能距离您需要的内容有一千英里,但您可以在 linux 下使用“watch”之类的东西来寻找特定的文本。如果您要注销某个文件,您可以设置“watch”来监视文件中的某些文本并相应地发出指令。

于 2012-02-09T21:56:33.013 回答