带有Java Util日志记录的Java 8延迟调用
在博客文章“在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可以看出,有很多重載的方法用于“精確日志記錄”(接受顯式指定的類和方法名稱的兩個String的logp方法)以及用于接受實例的“常規日志記錄” 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延迟调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么手机定位不准确
- 下一篇: 苹果手机如何清理缓存和垃圾