[JAVA] Empêcher les erreurs dans le nom de l'enregistreur en copiant

Aperçu

Voici les conseils pour créer une instance Logger, qui sont également décrits dans la FAQ SLF4J. Voici une histoire et une solution à la déclaration de Logger.

[Problème] Nom de l'enregistreur incorrect

Un bogue courant avec Logger est une erreur dans le nom du Logger. Cela a tendance à se produire si vous copiez la déclaration Logger à partir d'une autre source.

Exemple de spécification du mauvais nom de l'enregistreur


public class MyClass {
  private static final Logger LOGGER = LoggerFactory.getLogger(User.class); //punaise!Continuez à copier à partir du code de la classe User
  //...
}

[Solution] Utiliser le descripteur de méthode

En utilisant MethodHandle [^ mh] introduit à partir de Java7, vous pouvez obtenir l'objet Class appelant de manière statique. (Utilisez la méthode statique [^ mhs] de la classe MethodHandles (méthode de retour [^ mhs-lookup]) ← Notez qu'il ne s'agit pas de la classe MethodHandle [^ mh])

Obtenir l'objet de classe


Class<?> clazz = MethodHandles.lookup().lookupClass();

L'idiome de la génération de Logger utilisant ceci est publié dans la FAQ SLF4J [^ slf4j]. Dans ce cas, vous pouvez le copier et l'utiliser tel quel (sans réécrire le nom Logger de l'argument).

Idiome de génération d'enregistreur


import java.lang.invoke.MethodHandles;
      
public class MyClass {
  private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
  //...
}

Pour votre propre classe Logger

Si vous avez votre propre classe Logger, vous pouvez empêcher la spécification d'un nom de Logger incorrect en limitant les types d'argument de la méthode de fabrique comme indiqué ci-dessous. J'ai écrit sur ma propre classe Logger plus tôt. → Utilisez LocationAwareLogger pour votre propre enregistreur

Argument de méthode d'usine MethodHandles.Rechercher seulement


import java.lang.invoke.MethodHandles;

public class MyLocationAwareLogger {
  // (Omettre des parties sans rapport avec ce sujet)

  //Le constructeur est privé
  private MyLocationAwareLogger(org.slf4j.spi.LocationAwareLogger logger) {
    this.logger = logger;
  }

  //Méthode d'usine(Seule cette méthode est exposée)
  public static MyLocationAwareLogger getLogger(MethodHandles.Lookup lookup) {
    return getLogger(lookup.lookupClass());
  }

  //Les méthodes d'usine autres que celles ci-dessus sont privées
  private static MyLocationAwareLogger getLogger(Class<?> clazz) {
    org.slf4j.spi.LocationAwareLogger logger = (org.slf4j.spi.LocationAwareLogger) LoggerFactory.getLogger(clazz);
    return new MyLocationAwareLogger(logger);
  }

  // (Omettre des parties sans rapport avec ce sujet)
}

Génération d'enregistreurs


private static final MyLocationAwareLogger LOGGER = MyLocationAwareLogger.getLogger(java.lang.invoke.MethodHandles.lookup());
//Ce qui suit entraînera une erreur de compilation
// private static final MyLocationAwareLogger LOGGER_NG1 = MyLocationAwareLogger.getLogger(User.class);
// private static final MyLocationAwareLogger LOGGER_NG2 = MyLocationAwareLogger.getLogger("User");

à la fin

Bien qu'il ne s'agisse que d'un nom d'enregistreur, si une valeur incorrecte est spécifiée, cela aura un effet négatif considérable sur l'analyse des défauts. Je pense qu'il y a beaucoup de gens qui ont été trompés par le nom de Logger et sont tombés dans l'enquête sans fin sur des pièces sans rapport avec le bug. C'est une astuce facile à introduire, alors essayez-la.

Recommended Posts

Empêcher les erreurs dans le nom de l'enregistreur en copiant
J'ai vérifié le nom du package référencé par la classe contenue dans le fichier JAR
Trier par plusieurs champs dans la classe
Nommer et appeler explicitement des méthodes de classe parent dans Ruby
Quand tu te perds dans le nom de la classe
Personnalisez le nom du bean défini par Spring component-scan
[Java] Jugement en saisissant des caractères dans le terminal
Format de la sortie du journal par Tomcat lui-même dans Tomcat 8
[Kotlin] Récupère le nom de l'argument du constructeur par réflexion
Lire la capture de paquets obtenue par tcpdump avec Java
Obtenez le nom d'anime de ce terme en grattant
Obtenez le nom du scénario de test dans la classe de test JUnit
Inclure le code source généré par Doma dans le JAR source