2013-07-24 4 views
7

Nella documentazione per slf4j si dice che il legame avviene durante complie tempo:.Come si lega slf4j all'implementazione? Lo fa davvero durante la compilazione?

"SLF4J non si basa su alcun macchine speciali class loader In effetti, ogni legame è cablato al momento della compilazione SLF4J di usare una e una sola Per esempio, l'associazione slf4j-log4j12-1.7.5.jar è vincolata al momento della compilazione per usare log4j. Nel tuo codice, oltre a slf4j-api-1.7.5.jar, puoi semplicemente eliminare uno e solo un legame a tua scelta sul percorso del percorso di classe appropriato.Non inserire più di una rilegatura sul percorso della classe.Qui è un'illustrazione grafica dell'idea generale. " http://www.slf4j.org/manual.html

Come funziona?

risposta

3

Da quello che ho visto, lo fa aspettando che la classe StaticLoggingBinder si trovi nello stesso pacchetto (org.slf4j.impl), indipendentemente dall'implementazione - quindi la trova sempre nello stesso posto.

+1

Che importa se ho più di uno StaticLoggingBinder nello stesso package (org.slf4j.impl)? Ad esempio, ho slf4j-log4j12.jar e logback-classic.jar nello stesso progetto, quale sarà il binding? –

+0

Probabilmente un po 'casuale - ma immagino che verrà usato quello per primo sul classpath (o forse l'ultimo ...) –

+0

Sì, sono d'accordo con te. –

0

Tecnicamente, non esiste alcun "legame" magico in fase di compilazione. Il "binding" si è verificato quando gli sviluppatori SLF4J hanno creato librerie per gestire i framework di registrazione Java più popolari.

Quando i documenti dicono che il "binding è cablato in fase di compilazione", significa che gli sviluppatori SLF4J hanno creato una libreria mirata per un particolare framework di registrazione Java. SLF4J ha librerie dedicate alla registrazione di Java, a Jakarta Commons Logging, a Log4J e all'output della console. È necessario includere solo uno di queste librerie in fase di esecuzione affinché SLF4J possa creare correttamente i messaggi di registro.

Per ulteriori informazioni su come funziona SLF4J: A more visual way to understand SLF4J.

0

Era anche la mia domanda e vorrei aggiungere la mia risposta, poiché ho trovato che le altre due risposte non erano abbastanza chiare (anche se sono perfettamente corrette).

primo luogo, verificare questa linea nella realizzazione di LoggerFactory.bind() a slf4j-api (link)

// the next line does the binding 
StaticLoggerBinder.getSingleton(); 

C'è una classe chiamata org.slf4j.impl.StaticLoggerBinder. Controlla la sua implementazione su github.

Ora andare avanti e scaricare il slf4j-api.jar dal repository centrale di Maven, estrarlo e trovare il file StaticLoggerBinder.class.

Non provare! Non puoi In effetti l'intero org.slf4j.impl è stato rimosso dal pacchetto. Controllare il pom.xml del progetto:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-antrun-plugin</artifactId> 
    <executions> 
     <execution> 
     <phase>process-classes</phase> 
     <goals> 
     <goal>run</goal> 
     </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <tasks> 
     <echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo> 
     <delete dir="target/classes/org/slf4j/impl"/> 
     </tasks> 
    </configuration> 
    </plugin> 

scorso, controllare uno dei pacchetti di legame del SLF4J, ad esempio slf4j-simple. Riesci a trovare la classe org.slf4j.impl.StaticLoggerBinder?

In somma, quando si dispone di slf4j-api.jar insieme a uno (e solo uno) dei pacchetti di bind nel proprio ambiente di runtime, si ha solo una classe org.slf4j.impl.StaticLoggerBinder che esegue il binding.

2

Ecco il codice sorgente di slf4j. Slf4j troverà tutta la classe nel percorso della classe il cui percorso è "org/slf4j/impl/StaticLoggerBinder.class". E se ce ne sono più di uno, jvm ne prenderà solo uno a caso.Più detaile potete vedere qui: http://www.slf4j.org/codes.html#multiple_bindings

// We need to use the name of the StaticLoggerBinder class, but we can't 
// reference 
// the class itself. 

private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class"; 

static Set<URL> findPossibleStaticLoggerBinderPathSet() { 
// use Set instead of list in order to deal with bug #138 
// LinkedHashSet appropriate here because it preserves insertion order 
// during iteration 
    Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>(); 
    try { 
     ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader(); 
     Enumeration<URL> paths; 
     if (loggerFactoryClassLoader == null) { 
      paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH); 
     } else { 
      paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH); 
     } 
     while (paths.hasMoreElements()) { 
      URL path = paths.nextElement(); 
      staticLoggerBinderPathSet.add(path); 
     } 
    } catch (IOException ioe) { 
     Util.report("Error getting resources from path", ioe); 
    } 
    return staticLoggerBinderPathSet; 
} 
Problemi correlati