2011-01-27 23 views
8

Sono l'unico manutentore su una base di codici in cui la registrazione viene eseguita utilizzando la registrazione dei comuni Apache.Il registro non statico può essere giustificato?

Tutte le classi contiene questi due importazioni:

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

Poi un sacco di classi contiene esemplificazione di registro non statico come questo:

/** The log. */ 
private Log log = LogFactory.getLog(Xyz.class); 

Può questo essere giustificato?

Posso tranquillamente cambiare tutte queste chiamate statiche?

EDIT Per quanto riguarda i casi particolari in cui può (a quanto pare) essere a portata di mano: "? Possibile accedere non statica in tutto il codebase essere giustificata" la mia domanda è davvero più

risposta

5

È necessario prestare particolare attenzione quando i logger non statici vengono inizializzati come avviene con lo snippet di codice nelle classi Serializable.

Innanzitutto perché Log non è serializzabile, quindi anche qualsiasi tentativo di serializzazione della classe avrà esito negativo. Se dichiari il tuo logger transient allora, come è logico fare, il tuo campo log non verrà inizializzato dopo la deserializzazione, quindi riceverai un NPE mentre provi a registrare le cose. Non è una bella situazione.

Quindi, per sommarlo, è possibile avere logger non statici, se si preferisce, ma assicurarsi che siano inizializzati prima di usarli. Ma a parte questo, non mi preoccuperei molto dei logger non statici, la maggior parte delle implementazioni di logging restituiranno sempre lo stesso oggetto logger comunque (log4j lo fa sicuramente).

8

Dipende. Questo è dal documentation:

Si noti che per il codice dell'applicazione, dichiarando il membro registro come "statica" è più efficiente come un unico oggetto di registro viene creato per classe, ed è consigliato. Tuttavia questo non è sicuro da fare per una classe che può essere distribuita tramite un classloader "condiviso" in un servlet o un contenitore j2ee o un ambiente simile. Se la classe può essere invocata con diversi valori thread-context-classloader impostati, il membro non deve essere dichiarato statico. L'uso di "statico" dovrebbe quindi essere evitato nel codice all'interno di qualsiasi progetto di tipo "libreria".

+0

Avendo letto che la documentazione, non è chiaro per me ciò che è sbagliato con dichiarare un campo Registro statico anche nell'ambiente classloader condiviso. Il parametro della classe LogFactory.getLog() può essere modificato in una stringa (Xyz.class.getName()) per una cosa e, a parte questo, dove si trova il danno del logger a cui si accede da classi con diversi programmi di caricamento del contesto thread? I metodi di log dovrebbero essere comunque thread-safe e se non hai problemi più grandi. Qualcuno può fornire una descrizione chiara di cosa può andare storto con i riferimenti log statici? –

+1

@Dov Wasserman Buona domanda, ma per essere onesto con te, non capisco nemmeno il punto della registrazione dei beni comuni. :) – biziclop

2

Un'istanza in cui un logger non statico è utile è una sorta di classe base che fornisce un'istanza di registro alle classi figlio (per comodità). Considerare il seguente esempio:

public abstract class Pet 
{ 
    protected Log log; 

    public Pet() 
    { 
     log = LogFactory.getLog(this.getClass()); 
    } 

    public void wash() 
    { 
     log.info("Get the hose."); 
    } 
    ... 
} 

public class Cat extends Pet 
{ 
    ... 
    public void doSomethingUseful() 
    { 
     log.warn("I can't, I am a cat."); 
    } 
} 

In questo esempio, la registrazione verrà dall'istanza di registro "Cat". È una giustificazione validaper non utilizzare un logger statico? Forse non per i messaggi registrati dalla classe Cat, ma i messaggi registrati dalla classe Pet sotto l'istanza del registro Cat potrebbero essere utili.

0

Ecco un articolo che implica l'opposto. Di fatto, in situazioni complesse, possono sorgere problemi di caricamento di classe con i logger statici nelle librerie. Quindi sì, i logger non statici possono essere giustificati.

considerare tuttavia, il caso in cui una classe utilizzando "log Log private static = ..." viene distribuito attraverso un ClassLoader che si trova nella discendenza di molteplici "applicazioni" presumibilmente indipendenti. In questo caso, il membro del registro è inizializzato solo una volta, poiché esiste una sola copia della classe. L'inizializzazione (in genere) si verifica la prima volta che un codice prova per creare un'istanza di quella classe o richiamare un metodo statico su di essa. Quando si verifica l'inizializzazione della classe , quale deve essere il membro di registro impostato su ?

http://wiki.apache.org/commons/Logging/StaticLog

Problemi correlati