2017-01-04 51 views
6

czytałem nowe funkcje Log4j2 i istnieje funkcja, która umożliwiaJava Lambda Expression i logowania

"Java wsparcie 8 lambda dla leniwych rejestrowania"

i daje dwa przykłady

pierwszym z nich jest złą praktyką

// pre-Java 8 style optimization: explicitly check the log level 
// to make sure the expensiveOperation() method is only called if necessary 
if (logger.isTraceEnabled()) { 
    logger.trace("Some long-running operation returned {}", expensiveOperation()); 
} 

A druga jest dobra praktyka

// Java-8 style optimization: no need to explicitly check the log level: 
// the lambda expression is not evaluated if the TRACE level is not enabled 
logger.trace("Some long-running operation returned {}",() -> expensiveOperation()); 

Gdzie dokonuje się sprawdzania, czy wymagany poziom rejestru jest włączony? "logger.isTraceEnabled()"?

Odpowiedz

7

Gdzie dokonuje się sprawdzanie, czy wymagany poziom rejestru jest włączony?

Wewnątrz metody logger.trace().

Ta sztuczka polega jednak na sposobie przekazywania argumentu. Styl pre-java8 obliczył wartość w czasie wywoływania logger.trace.

logger.trace(..., expensiveOperation()); 

Java 8 styl używa Supplier

logger.trace(...,() -> expensiveOperation()); 

Więc expensiveOperation() nazywa się tylko na żądanie - wewnątrz metody trace.

Wystarczy popatrzeć na realizację java.util.logging.Logger.log():

public void log(Level level, Supplier<String> msgSupplier) { 
    if (!isLoggable(level)) { 
     return; 
    } 
    LogRecord lr = new LogRecord(level, msgSupplier.get()); // <-- here is the expensive computation 
    doLog(lr); 
} 
2

trace metoda (lub jakakolwiek inna metoda rejestrowania dla tego względu) już sprawdza poziom rejestrowania wewnętrznie. Sprawdzanie go w programie wywołującym to również optymalizacja, aby uniknąć obliczania expensiveOperation(). Przy nowej składni języka Java 8 nie przekazujemy obliczonej wartości expensiveOperation(), ale lambda, która wywołuje ją tylko w razie potrzeby.

Należy zauważyć, że chociaż log4j nie wdrożyć go, można teoretycznie mają takie samo zachowanie, bez fantazji Java 8 składni poprzez zdefiniowanie interfejsu dla operatora wartości, i metoda rejestrowania nazwać:

// Interface definition 
public interface ValueProvider { 
    String getValue(); 
} 

// Calling it from the main code with an anonymous implementation: 
logger.trace("Some long-running operation returned {}", 
      new ValueProvider() { 
       public String getValue() { 
        return expensiveOperation(); 
       } 
      });