Java 将Log4j记录器放入多个类中

Java 将Log4j记录器放入多个类中,java,log4j,Java,Log4j,我想在我的程序中的很多类中添加日志记录。我是否需要为每个需要记录器的类添加行来定义记录器?我希望避免在程序中传递logger对象 public class SomeClass { static Logger logger = Logger.getLogger(SomeClass.class); ....... 如果我这样做了,我能通过这个电话了解它的类吗 或者是否有其他方法可以做到这一点是的,您需要在每个类中添加行。 如果您的记录器是静态的,就像您的示例一样,那么每次都需要像指定Som

我想在我的程序中的很多类中添加日志记录。我是否需要为每个需要记录器的类添加行来定义记录器?我希望避免在程序中传递logger对象

public class SomeClass {
  static Logger logger = Logger.getLogger(SomeClass.class);
  .......
如果我这样做了,我能通过这个电话了解它的类吗
或者是否有其他方法可以做到这一点

是的,您需要在每个类中添加行。 如果您的记录器是静态的,就像您的示例一样,那么每次都需要像指定SomeClass.class一样指定类。如果将记录器设置为非静态,则可以使用此.getClass,它将更便于剪切粘贴:

public class SomeClass {
  private Logger logger = Logger.getLogger(this.getClass());
  .......

是的,您需要为每个类添加行。 如果您的记录器是静态的,就像您的示例一样,那么每次都需要像指定SomeClass.class一样指定类。如果将记录器设置为非静态,则可以使用此.getClass,它将更便于剪切粘贴:

public class SomeClass {
  private Logger logger = Logger.getLogger(this.getClass());
  .......
不,你不需要这样做,但这是一种习惯做法,也是一种很好的做法。Log4j是围绕着这个假设构建的,人们会以这种方式使用它。它为您提供了免费的日志事件发布地点的位置,以及对整个日志记录器分支的日志级别的轻松管理

理论上,您可以在多个类之间共享一个记录器,甚至只有一个全局记录器;记录器是线程安全的,并且无论如何在附加对象时都需要同步,所以您的性能不会受到影响。您还可以为它命名任何您想要的名称,而不需要使用类名。但是,由于我上面提到的原因,不建议这样做

另外,您不需要将引用设置为静态,因为log4j确保您只能创建一个具有给定名称的记录器,您不会因为将其存储在实例变量中而浪费内存。

不,您不需要这样做,但这是一种习惯做法,也是一种很好的做法。Log4j是围绕着这个假设构建的,人们会以这种方式使用它。它为您提供了免费的日志事件发布地点的位置,以及对整个日志记录器分支的日志级别的轻松管理

理论上,您可以在多个类之间共享一个记录器,甚至只有一个全局记录器;记录器是线程安全的,并且无论如何在附加对象时都需要同步,所以您的性能不会受到影响。您还可以为它命名任何您想要的名称,而不需要使用类名。但是,由于我上面提到的原因,不建议这样做


另外,您不需要将引用设置为静态,因为log4j确保您只能创建一个具有给定名称的记录器,您不会因为将其存储在实例变量中而浪费内存。

我发现方便的一个替代方法是创建一个抽象类,为您创建记录器:

public abstract class AbstractLoggingThing {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    protected Logger getLog() {
        return log;
    }
}
然后按照惯例,从它继承的每个类都有一个正确配置的记录器,您不必到处都有相同的、愚蠢的代码。项目中的大多数类都可以很容易地将其包含在继承层次结构中,对于那些不能包含的类,无论出于何种原因,您仍然可以回到旧的样式。您还可以添加一些方便的方法,如:

    protected void info(String message, Object... args) {
        // What goes here depends on your logging library
    }

我发现方便的另一种方法是创建一个抽象类,为您创建记录器:

public abstract class AbstractLoggingThing {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    protected Logger getLog() {
        return log;
    }
}
然后按照惯例,从它继承的每个类都有一个正确配置的记录器,您不必到处都有相同的、愚蠢的代码。项目中的大多数类都可以很容易地将其包含在继承层次结构中,对于那些不能包含的类,无论出于何种原因,您仍然可以回到旧的样式。您还可以添加一些方便的方法,如:

    protected void info(String message, Object... args) {
        // What goes here depends on your logging library
    }

请注意,这样做的效果是,如果有人创建了一个公共类子类扩展了SomeClass,那么子类从SomeClass继承的每个方法都将获得一个子类的记录器-这可能是也可能不是期望的结果。您也不必将它添加到每个类中。事实上,它有这么多的UPVOUT似乎表明这不是常识。请注意,如果有人创建一个公共类子类来扩展SomeClass,然后,子类从某个类继承的每个方法都会得到子类的记录器——这可能是也可能不是期望的结果。您必须将它添加到每个类中也是不正确的。事实上,它有这么多的投票,这似乎表明这不是常识。使用Eclipse代码模板:使用Eclipse代码模板:我不会这么做。在具有多重继承的语言中,它可能做得很好,但在Java中,它会导致创建与基类紧密耦合的god对象和代码。作为一个软件包中的一种方便方法,它可能很好,但对于整个应用程序来说肯定不行。@MaDa:一点也不。如果这对一个包有好处,为什么不在更大的范围内呢?把它想象成一个穷人的聚会。如果我使用的是AspectJ,我可能会将此代码编入其中,而不是继承它。此外,我成功地使用了这个
在没有有害副作用的良好规模项目上的方法。它更像是对象的替代品,而不是其他任何东西。这非常有帮助,而且还有一个额外的好处,就是大多数日志都是集中管理的。对于那些仍然使用commons logging或log4j的用户,它还可以消除那些疯狂的if log.isXxxEnabled调用的需要……我们还在一个Java项目中使用了这种模式,该项目对使用外部库有着极大的限制——它工作得很好,但是这些年来,在这个超级duper基类中添加另一个方法的诱惑是不可抗拒的,并且它发展到了一个巨大的规模。我绝对反对不受约束地使用这种模式。AspectJ更好,但它相当先进。我不会这么做。在具有多重继承的语言中,它可能做得很好,但在Java中,它会导致创建与基类紧密耦合的god对象和代码。作为一个软件包中的一种方便方法,它可能很好,但对于整个应用程序来说肯定不行。@MaDa:一点也不。如果这对一个包有好处,为什么不在更大的范围内呢?把它想象成一个穷人的聚会。如果我使用的是AspectJ,我可能会将此代码编入其中,而不是继承它。此外,我在一个规模不错的项目中成功地使用了这种方法,没有任何有害的副作用。它更像是对象的替代品,而不是其他任何东西。这非常有帮助,而且还有一个额外的好处,就是大多数日志都是集中管理的。对于那些仍然使用commons logging或log4j的用户,它还可以消除那些疯狂的if log.isXxxEnabled调用的需要……我们还在一个Java项目中使用了这种模式,该项目对使用外部库有着极大的限制——它工作得很好,但是这些年来,在这个超级duper基类中添加另一个方法的诱惑是不可抗拒的,并且它发展到了一个巨大的规模。我绝对反对不受约束地使用这种模式。AspectJ更好,但它相当先进。