2011-01-27 13 views
8

Soy el único mantenedor en una base de código donde el registro se hace usando el registro de Apache commons.¿Se puede justificar el registro no estático?

Todas las clases contiene estos dos importaciones:

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

entonces un montón de clases contiene no instanciación registro estático como sigue:

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

Puede esto ser justificado?

¿Puedo cambiar de forma segura todas estas a llamadas estáticas?

EDITAR En cuanto a los casos especiales en que puede (al parecer) ser muy útil: "¿Puede registro no estática todo el código base será justificado" Mi pregunta es realmente más

Respuesta

5

usted tiene que ser muy cuidadoso con la que tienen los registradores no estáticos inicializado la forma en el fragmento de código está haciendo en Serializable clases.

En primer lugar porque Log no es serializable, por lo que cualquier intento de serializar su clase también fallará. Si declara su registrador transient, como es lógico, su campo log no se inicializará después de la deserialización, por lo que obtendrá un NPE mientras intenta registrar cosas. No es una situación muy agradable.

Para resumir, puede tener registradores no estáticos si lo prefiere, pero asegúrese de que estén inicializados antes de usarlos. Pero aparte de eso, no me preocuparía mucho acerca de los registradores no estáticos, la mayoría de las implementaciones de registro siempre devolverán el mismo objeto registrador de todos modos (log4j definitivamente lo hace).

8

Depende. Esto es de la documentation:

Tenga en cuenta que para el código de la aplicación, declarando el miembro de registro como "estática" es más eficiente ya que se crea un objeto de registro por clase, y se recomienda. Sin embargo, esto no es seguro para una clase que puede implementarse mediante un cargador de clases "compartido" en un contenedor servlet o j2ee o en un entorno similar. Si la clase puede terminar invocada con diferentes valores de thread-context-classloader establecidos, entonces el miembro no debe declararse estático. Por lo tanto, debe evitarse el uso de "estático" en el código dentro de cualquier proyecto de tipo "biblioteca".

+0

Después de leer que la documentación, no está claro para mí lo que está mal con la que se declara un campo de registro como estática, incluso en el entorno cargador de clase compartida. El parámetro de clase LogFactory.getLog() se puede cambiar a una Cadena (Xyz.class.getName()) por una cosa, y aparte de eso, ¿dónde está el daño del registrador al que se accede desde clases con diferentes cargadores de clase de contexto de subprocesos? Los métodos de registro deberían ser seguros para subprocesos de todos modos y si no tienes problemas mayores. ¿Alguien puede proporcionar una descripción clara de lo que puede salir mal con las referencias de registro estáticas? –

+1

@Dov Wasserman Buena pregunta, pero para ser honesto, ni siquiera entiendo el punto de la registración de los bienes comunes. :) – biziclop

2

Una instancia en la que un registrador no estático es práctico es una especie de clase base que proporciona una instancia de registro a las clases secundarias (como conveniencia). Considere el siguiente ejemplo:

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."); 
    } 
} 

En este ejemplo, el registro será desde la instancia de registro "Cat". ¿Es esto una justificación válida para no usar un registrador estático? Tal vez no para los mensajes registrados desde la clase Cat, pero los mensajes registrados de la clase Pet en la instancia de registro de Cat podrían ser útiles.

0

Aquí hay un artículo que implica lo contrario. De hecho, en situaciones complejas, pueden surgir problemas de carga de clases con los registradores estáticos en las bibliotecas. Entonces, sí, los registradores no estáticos pueden justificarse.

Sin embargo Considere el caso cuando una clase usando "log log estática privada = ..." se despliega a través de un cargador de clases que está en la ascendencia de múltiples "aplicaciones" supuestamente independientes. En este caso, el miembro de registro es inicializado solo una vez, porque solo hay una copia de la clase. Esa inicialización (normalmente) ocurre la primera vez que un código intenta para instanciar esa clase o llamar a un método estático en ella. Cuando se produce la inicialización de la clase, ¿a qué se debe asignar el miembro de registro ?

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

Cuestiones relacionadas