【问题标题】:LoggerFactory.getLogger(ClassName.class) vs LoggerFactory.getLogger(this.getClass().getName())LoggerFactory.getLogger(ClassName.class) 与 LoggerFactory.getLogger(this.getClass().getName())
【发布时间】:2015-11-18 11:41:17
【问题描述】:

我正在努力提高我在 Java 中的优化技能。为了实现这一点,我制作了一个旧程序,我正在尽我所能让它变得更好。在这个程序中,我使用 SL4J 进行日志记录。为了得到我所做的记录器:

private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

在我编写代码时,我认为这是最好的选择,因为我删除了对类名的引用(可能会被重构)。但现在我不再那么确定了......

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

另一方面,保留对类名的引用,但它删除了一个方法调用。对于一个班级来说,这可能不会带来很大的性能提升,但是当你有很多班级时,这可能会有所作为。

所以我的问题是:

哪种方法更好?使用类名还是通过反射获得它?

请用利弊激发你的回答。谢谢。

【问题讨论】:

    标签: java logging optimization reflection slf4j


    【解决方案1】:

    迟到!

    因为我将来可能会搜索这个。

    有一种方法可以通过使用 Java 7 的 MethodHandles 类来创建复制/粘贴友好的 Logger 实例(当然这几乎不是做某事的好理由!)。

    private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    

    【讨论】:

      【解决方案2】:

      我会在这里分享我的意见。我想说的是,从性能的角度来看,您不应该被打扰。可能在代码中有比这东西可以优化得多的部分:)

      现在,关于您的问题。看看LoggerFactory's代码

      注意getLogger(Class<?> name)只是调用了重载的方法:

      Logger logger = getLogger(clazz.getName());
      

      并进行一些额外的计算。所以使用String的方法显然要快一些。

      一般来说,该模式是将 Logger 引用维护为类中的静态字段,如下所示:

      public class SomeClass {
         private static final Logger LOG =   LoggerFactory.getLogger(SomeClass.class);
      }
      

      在这种情况下,您不能真正使用this.getClass(),因为this 实际上并不存在(您在静态上下文中运行)。

      根据我的经验,最好使用ClassName.getClass() 作为参数,除非您真的想使用来自不同类的相同记录器。在这种情况下,您最好使用一些表示记录器的逻辑常量。

      例如,假设您尝试使用 3 个不同的类来访问数据库。 因此,您创建了 logger 'DB',分配了一个将写入 database.log 的文件 appender,并且您希望在这 3 个不同的类中重用相同的 logger。

      所以你应该使用以下代码:

      public class SomeClass {
         private static final Logger LOG =   LoggerFactory.getLogger("DB");
      }
      

      希望对你有帮助

      【讨论】:

        【解决方案3】:

        我通常做的是

        private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
        

        然而,成语

        protected final Logger log = LoggerFactory.getLogger(getClass());
        

        同样常见。 In this question您可以找到有关这些约定的更多信息。

        【讨论】:

        • 第一种的好处是只发生一次,第二种是每次创建对象时发生。
        • 使用getClass()的好处是,如果你登录一个抽象类,使用它的子类不会引用抽象类的名字
        【解决方案4】:

        我更喜欢

        Logger logger = LoggerFactory.getLogger(ClassName.class);
        

        因为

        this.getClass() 
        

        可以被其中一个班级孩子覆盖,您将在日志中看到孩子班级名称。有时可能会令人困惑,因为日志实际上是在父类中执行的

        【讨论】:

          【解决方案5】:

          在静态上下文中,您不能使用 LoggerFactory.getLogger(getClass()) 或 LoggerFactory.getLogger(this.getClass().getName())

          然后你必须使用LoggerFactory.getLogger(ClassName.class)

          无论如何,我更喜欢 Lombok 的 @Log4j2 ,代码更少,并且可以完成工作:https://projectlombok.org/api/lombok/extern/log4j/Log4j2.html

          【讨论】:

            【解决方案6】:

            如果不想每次声明logger时都写类名,可以使用以下实用方法:

                public static org.slf4j.Logger getLogger() {
                    final Throwable t = new Throwable();
                    t.fillInStackTrace();
                    return LoggerFactory.getLogger(t.getStackTrace()[1].getClassName());
                }
            

            方法可以这样使用:

            private static final Logger LOG = TheClassContainingTheMethod.getLogger();
            

            使用这种方法,所有类的记录器声明始终相同。

            【讨论】:

            • 避免打字和冗余的好方法!
            【解决方案7】:

            使用这个

            private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
            
            }
            // logic
            try
            {
            // todo
            }
            
            catch (NullPointerException e) {
                    logger.error("Error:-" + e.getMessage());
                      return ResponseUtil.errorResponse(e.getMessage());
                    }
            
                    catch (Exception e) {
                        logger.error("Error:-" + e.getMessage());
                        return ResponseUtil.errorResponse(e.getMessage());
                    }
            

            【讨论】:

            • 需要有哪些导入以及使用它的 maven 依赖项
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-17
            相关资源
            最近更新 更多