在博客文章“在Log4j2中更好地执行非日志记录器调用”中 ,我介绍了可以在Log4j 2中使用的方法,这些方法可以减少或避免在基于指定日志级别实际上根本未记录的日志语句中调用方法。 作为讨论的一部分,我介绍了Log4j 2对使用lambda表达式的基于Java 8的延迟执行的支持。 在本文中,我将演示如何使用内置的java.util.logging ( JUL )支持来使用lambda表达式延迟执行日志语句中的方法,其方式类似于Log4j 2所支持的方式。

java.util.logging.Logger类级别的Javadoc文档描述了JUL对延迟执行的支持:

一组方法也可以使用“ msgSupplier”而不是“ msg”参数。 这些方法需要供应商

该函数仅在基于有效日志级别实际记录消息时才调用以构造所需的日志消息,从而消除了不必要的消息构造。

浏览java.util.logging.Logger的公共API,可以快速浏览该注释中引用的方法,该方法使用供应商来允许推迟方法调用,直到真正知道需要进行日志为止。 接受内置功能接口 java.util.function.Supplier的实例作为参数的code.util.logging.Logger方法。 例如,下一个屏幕快照使用一些接受Supplier的方法来捕获HTML呈现的Javadoc的一小部分。

我喜欢使用javap轻松查看Java类的公共API。 在这种情况下,可以通过执行$JAVA_HOME/jre/lib目录javap -classpath rt.jar java.util.logging.Logger的命令javap -classpath rt.jar java.util.logging.Logger来完成此操作(假设已配置了JAVA_HOME环境变量)。 下一个屏幕快照描述了该命令的执行以及结果的第一部分。 屏幕快照之后是输出的文本版本, 强调Supplier的使用。

Compiled from "Logger.java"
public class java.util.logging.Logger {static final java.lang.String SYSTEM_LOGGER_RB_NAME;public static final java.lang.String GLOBAL_LOGGER_NAME;public static final java.util.logging.Logger global;static final boolean $assertionsDisabled;public static final java.util.logging.Logger getGlobal();protected java.util.logging.Logger(java.lang.String, java.lang.String);java.util.logging.Logger(java.lang.String, java.lang.String, java.lang.Class<?>, java.util.logging.LogManager, boolean);void setLogManager(java.util.logging.LogManager);public static java.util.logging.Logger getLogger(java.lang.String);public static java.util.logging.Logger getLogger(java.lang.String, java.lang.String);static java.util.logging.Logger getPlatformLogger(java.lang.String);public static java.util.logging.Logger getAnonymousLogger();public static java.util.logging.Logger getAnonymousLogger(java.lang.String);public java.util.ResourceBundle getResourceBundle();public java.lang.String getResourceBundleName();public void setFilter(java.util.logging.Filter) throws java.lang.SecurityException;public java.util.logging.Filter getFilter();public void log(java.util.logging.LogRecord);public void log(java.util.logging.Level, java.lang.String);public void log(java.util.logging.Level, java.util.function.Supplier<java.lang.String>);public void log(java.util.logging.Level, java.lang.String, java.lang.Object);public void log(java.util.logging.Level, java.lang.String, java.lang.Object[]);public void log(java.util.logging.Level, java.lang.String, java.lang.Throwable);public void log(java.util.logging.Level, java.lang.Throwable, java.util.function.Supplier<java.lang.String>);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.util.function.Supplier<java.lang.String>);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.Object);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.Object[]);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable);public void logp(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.Throwable, java.util.function.Supplier<java.lang.String>);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.String);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object[]);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.util.ResourceBundle, java.lang.String, java.lang.Object...);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable);public void logrb(java.util.logging.Level, java.lang.String, java.lang.String, java.util.ResourceBundle, java.lang.String, java.lang.Throwable);public void entering(java.lang.String, java.lang.String);public void entering(java.lang.String, java.lang.String, java.lang.Object);public void entering(java.lang.String, java.lang.String, java.lang.Object[]);public void exiting(java.lang.String, java.lang.String);public void exiting(java.lang.String, java.lang.String, java.lang.Object);public void throwing(java.lang.String, java.lang.String, java.lang.Throwable);public void severe(java.lang.String);public void warning(java.lang.String);public void info(java.lang.String);public void config(java.lang.String);public void fine(java.lang.String);public void finer(java.lang.String);public void finest(java.lang.String);public void severe(java.util.function.Supplier<java.lang.String>);public void warning(java.util.function.Supplier<java.lang.String>);public void info(java.util.function.Supplier<java.lang.String>);public void config(java.util.function.Supplier<java.lang.String>);public void fine(java.util.function.Supplier<java.lang.String>);public void finer(java.util.function.Supplier<java.lang.String>);public void finest(java.util.function.Supplier<java.lang.String>);public void setLevel(java.util.logging.Level) throws java.lang.SecurityException;final boolean isLevelInitialized();public java.util.logging.Level getLevel();public boolean isLoggable(java.util.logging.Level);public java.lang.String getName();public void addHandler(java.util.logging.Handler) throws java.lang.SecurityException;public void removeHandler(java.util.logging.Handler) throws java.lang.SecurityException;public java.util.logging.Handler[] getHandlers();java.util.logging.Handler[] accessCheckedHandlers();public void setUseParentHandlers(boolean);public boolean getUseParentHandlers();public void setResourceBundle(java.util.ResourceBundle);public java.util.logging.Logger getParent();public void setParent(java.util.logging.Logger);final void removeChildLogger(java.util.logging.LogManager$LoggerWeakRef);static java.util.logging.Logger$LoggerBundle access$000();static java.util.logging.Logger$LoggerBundle access$100();static {};
}

java.util.logging.Logger的公共API可以看出,有很多重载的方法用于“精确日志记录”(接受显式指定的类和方法名称的两个Stringlogp方法)以及用于接受实例的“常规日志记录” Supplier 。 这些方法仅在将日志记录级别设置为足以写入日志语句的特定级别时,才可以处理供应商。

以下是接受Supplier实例的当前java.util.logging.Logger方法的列表:

  • 常规的特定级别的日志记录方法

    • public void severe (java.util.function.Supplier<java.lang.String>);
  • 需要规范日志级别的常规常规日志记录方法
    • public void log (java.util.logging.Level, java.util.function.Supplier<java.lang.String>);
  • “精确”的记录方法
    • public void logp (java.util.logging.Level, java.lang.String, java.lang.String, java.util.function.Supplier<java.lang.String>);

请记住,精确的日志记录方法(名称为logp )接受其类和方法名称的String参数,可以观察到JUL的延迟调用日志记录API与Log4j 2的实现之间的最大区别之一:JUL的实现不允许“消息”字符串,作为其日志记录方法的单独(附加)参数提供。

在我以前的博客文章中 ,我演示了Log4j 2的org.apache.logging.log4j.Logger.debug(String message,Supplier <?> ... paramSuppliers)方法的使用,该方法除了延迟执行提供的Supplier之外还接受消息String 。 。 Log4j 2的org.apache.logging.log4j.Logger提供了类似的方法来处理其他特定的日志级别( 错误 , 致命 , 信息 , 跟踪和警告 )以及具有明确级别的日志级别的常规日志记录。 通过与Supplier分开的String轻松提供上下文的额外灵活性是一个不错的选择。 还值得注意的是, Log4j 2的Logger还支持类似于java.util.logging.Logger提供的方法的各种日志方法,这些方法仅接受Supplier (没有任何上下文消息String )。

John Shepard在博客文章尝试Java 8的五大理由中写道:“现在可以从方法, log.isLogLevelEnabled和类似的方法中传递函数(并返回)了,不再需要在代码库中log.isLogLevelEnabled 。” 然后,他提供了一个简单的代码清单,演示了当消息上下文的单个String参数不属于方法签名的情况时,如何通过此API提供String上下文。 我在本文结尾处的示例将与此类似。

正如我在“在Log4j2中更好地执行非日志记录器调用”一文中所讨论的那样 ,由Java lambda表达式提供支持的延迟执行允许开发人员通过将传入对象的隐式和显式方法调用都推迟到lambda表达式被执行之前,从代码中删除日志保护。解决。 如果运行软件的日志记录级别的特定性低于消息的特定日志级别,则永远不会执行此操作。 换句话说,可以从下一个显示的代码清单转换代码,就像其后的较小代码清单一样。

if (logger.isLoggable(Level.FINE))
{logger.fine("GUARDED: " + slow);
}
if (logger.isLoggable(Level.FINE))
{logger.fine(expensiveOperation());
}
logger.fine(() -> "LAMBDA: " + slow);
logger.fine(this::expensiveOperation);

尽管软件开发中的许多事情实际上都是品味和见解的问题,但很难想象有很多理由支持较早的,更冗长的代码。 尽管有一些断言,但是更少的代码并不总是对每个人都可读。 但是,在这种情况下,我相信很少有开发人员会争辩说,更冗长的代码无论如何都比Java 8版本更好。

翻译自: https://www.javacodegeeks.com/2016/04/java-8-deferred-invocation-java-util-logging.html

带有Java Util日志记录的Java 8延迟调用相关推荐

  1. java util logging_简单日志记录,使用java.util.logging

    jsp+servlet+JavaBean模式下,可以做个简单的日志记录,日志文件保存在服务器.(Tomcat) package controller; import java.io.File; imp ...

  2. 怎样用java编写日志_用JAVA写一个日志类程序以供大家学习

    中华网络安全联盟    作者:jacoo    来源:本站原创    时间:2006-4-18 说明: 尽管JAVA类库和其他工具提供了不少的纪录程序运行状态的日志类,我发觉也 不是万能的,有时需要根 ...

  3. Scala error: type mismatch; found : java.util.List[?0] required: java.util.List[B]

    Scala error: type mismatch; found : java.util.List[?0] required: java.util.List[B] 目录 Scala error: t ...

  4. mybatis中传集合时 报异常 invalid comparison: java.util.Arrays$ArrayList and java.lang.String

    mybatis中传集合时 报异常 invalid comparison: java.util.Arrays$ArrayList and java.lang.String 参考文章: (1)mybati ...

  5. java.util.date转化成java.sql.date

    2019独角兽企业重金招聘Python工程师标准>>> java.util.Date curDate = new java.util.Date(); java.sql.Date da ...

  6. CompletableFuture源码详解之java.util.concurrent.CompletableFuture#runAsync(java.lang.Runnable)

    CompletableFuture#runAsync方法是用来执行无返回结果的异步程序,当执行一大堆业务逻辑代码,而又不需要返回结果的时候,可以使用此方法异步执行,提升接口性能,方法源码如下: /** ...

  7. JDK中提供的实现——通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例

    JDK中提供的实现 在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例. 1 ...

  8. 【ruoyi】java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoo

    前言 ruoyi 4.6.0 jdk1.8 错误 11:48:16.879 [http-nio-9031-exec-25] INFO c.r.f.s.r.UserRealm - [doGetAuthe ...

  9. 使用java.util.prefs.Preferences代替java.util.Properties

    典型的应用程序安装程序需要向用户询问几个选项,其中一些是配置问题,例如,应用程序应在其上运行的端口,应如何运行等.应用程序必须记住这些选项,并在每个选项中使用它们.跑. 解决此问题的标准方法是将这些选 ...

最新文章

  1. Study on Android【五】--自定义ContentProvider的语义
  2. php 实现贪吃蛇游戏,HTML5 贪吃蛇游戏实现思路及源代码_html5教程技巧
  3. django-websocket 安装及配置
  4. .so动态链接库文件
  5. Java 后台开发实习经历
  6. Mybatis事务隔离级别
  7. 拼多多回应漏洞:比薅羊毛更快的是“资损200亿”谣言的传播速度
  8. jenkins如何清缓存,jenkins在结账前清除存储库并强制克隆与清理
  9. 解决 Chrome 浏览器地址栏字体发虚模糊
  10. 钟平程序员逻辑英语——回归理性——中英文对切基本公式(1-1)
  11. 如何用地推进行有效获客降低成本提高效率?
  12. 平衡树(splay)学习笔记(详细,从入门到精(bao)通(ling))(持续更新)
  13. 友盟推送服务器配置文档,友盟使用指南
  14. 从头开始实现一个小型spring框架——手写Spring之集成Tomcat服务器
  15. 10分钟带你了解MSTP协议,附加配置MSTP实验
  16. (ZZ)毕业五年拉开大家差距的原因
  17. class-dump导出iOS系统私有库以及简单的私有API调用
  18. 山东大学-飞桨人工智能教育创新中心正式挂牌,打造区域产教融合新范式
  19. 从电影《流浪地球》中学项目管理
  20. Hbase按指定列族中指定列的列值查找数据Hbase命令

热门文章

  1. Redis 的 4 大法宝,2018 必学中间件
  2. 什么是AES算法?(整合版)
  3. Hibernate基本概念 (4)
  4. 全自动安装 linux光盘,CentOS 7.1全自动安装光盘制作详解
  5. spring中stereotype注解Component,Repository,Service,Controller
  6. vmware安装centos6-步骤小结
  7. tomcat(9)Session管理
  8. 一文理清Http2.0
  9. 使用工具将SQLServer转MYSQL的方法(连数据)
  10. java私有属性和私有方法_Java接口–历年来Java 9之旅–默认方法和私有方法