web-dev-qa-db-fra.com

LoggerFactory.getLogger (ClassName.class) vs LoggerFactory.getLogger (this.getClass (). GetName ())

J'essaie d'améliorer mes compétences d'optimisation en Java. Pour y parvenir, j'ai un ancien programme que j'ai créé et je fais de mon mieux pour l'améliorer. Dans ce programme, j'utilise SL4J pour la journalisation. Pour obtenir l'enregistreur, j'ai fait:

private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

Au moment où j'ai écrit le code, je pensais que c'était la meilleure option, car je supprimais une référence au nom de la classe (qui peut être refactorisée). Mais maintenant je n'en suis plus si sûr ...

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

De l'autre côté, conserve la référence au nom de classe, mais il supprime un appel de méthode. Cela peut ne pas être une grande amélioration des performances pour une classe, mais lorsque vous avez beaucoup de classe, cela peut être quelque chose.

Ma question est donc:

Quelle approche est la meilleure? Utiliser le nom de la classe ou le faire réfléchir?

S'il vous plaît, motivez votre réponse avec des avantages et des inconvénients. Je vous remercie.

14
Aurasphere

Je partagerai mon opinion ici. Je dirais que c'est le cas que vous ne devriez pas être dérangé du point de vue des performances. Probablement dans le code il y a des parties qui peuvent être optimisées beaucoup plus que cette chose :)

Maintenant, concernant votre question. Jetez un oeil sur LoggerFactory code

Notez que getLogger(Class<?> name) appelle simplement la méthode surchargée:

Logger logger = getLogger(clazz.getName());

Et fait quelques calculs supplémentaires. Ainsi, la méthode avec String est évidemment légèrement plus rapide.

En général, le modèle consiste à maintenir la référence Logger en tant que champ statique dans la classe, quelque chose comme ceci:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger(SomeClass.class);
}

Dans ce cas, vous ne pouvez pas vraiment utiliser this.getClass() car this n'existe pas réellement (vous exécutez dans un contexte statique).

D'après mon expérience, il vaut mieux utiliser la ClassName.getClass() comme paramètre, sauf si vous voulez vraiment utiliser le même enregistreur de différentes classes. Dans un tel cas, il vaut mieux utiliser une constante logique qui désigne l'enregistreur.

Par exemple, supposons que vous essayez d'utiliser 3 classes différentes pour accéder à la base de données. Donc, vous créez un enregistreur 'DB', attribuez un ajout de fichier qui écrira dans database.log et vous souhaitez réutiliser le même enregistreur parmi ces 3 classes différentes.

Vous devez donc utiliser le code suivant:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger("DB");
}

J'espère que cela t'aides

10
Mark Bramnik

Ce que je fais d'habitude c'est

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

Cependant, l'idiome

protected final Logger log = LoggerFactory.getLogger(getClass());

est tout aussi courant. Dans cette question vous pouvez trouver plus d'informations sur ces conventions.

7
francesco foresti

Je préfère

Logger logger = LoggerFactory.getLogger(ClassName.class);

Car

this.getClass() 

Peut être remplacé par l'un des enfants de la classe et vous verrez le nom de la classe enfant dans le journal. Parfois, cela peut être déroutant car le journal est en fait exécuté dans la classe parente

5
D. Rakov

Entrée tardive!

Comme je vais probablement le chercher à l'avenir.

Il existe un moyen de créer des instances de Logger conviviales pour copier/coller (étant donné que ce n'est presque jamais une bonne raison de faire quelque chose!) En utilisant Java 7.

private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
4
Mark McLaren

Si vous ne souhaitez pas écrire le nom de la classe chaque fois que vous déclarez un enregistreur, vous pouvez utiliser la méthode utilitaire suivante:

    public static org.slf4j.Logger getLogger() {
        final Throwable t = new Throwable();
        t.fillInStackTrace();
        return LoggerFactory.getLogger(t.getStackTrace()[1].getClassName());
    }

La méthode peut être utilisée de cette façon:

private static final Logger LOG = TheClassContainingTheMethod.getLogger();

Avec une telle approche, la déclaration de l'enregistreur est toujours la même pour toutes les classes.

0
baronKarza