Este tutorial da Mkyong sugere a inicialização de loggers desta maneira:
@Controller
public class WelcomeController {
private static final Logger logger = Logger.getLogger(WelcomeController.class);
// etc
}
Agora, presumivelmente, todas as outras classes que você usa, que possuem um logger, inicializarão seus loggers da mesma maneira.
Minha pergunta é - essa é a melhor maneira de fazer isso? Parece ... repetitivo.
getLogger()
o nome do logger para obter.Respostas:
Seu comentário diz que "detalhado" refere-se à necessidade de repetir essa linha de código em todas as classes. Minha primeira resposta é que, em geral, adicionar duas linhas de código (definição de variável mais declaração de importação) a todas as classes não é tão importante. Especialmente porque você só precisa adicioná-los às classes que têm comportamento e, portanto, precisam fazer log. Dito isto, a linha de código específica que você está usando é propensa a erros de copiar e colar (mais sobre isso mais tarde).
Mas, como você deseja alternativas, eis algumas, com motivos pelos quais você pode ou não usá-las.
Use um único logger para todo o aplicativo
Se você não se importa com o que a classe está relatando ou está disposto a colocar todo o contexto necessário na mensagem, um simples registrador singleton fará o trabalho:
Na minha opinião, um dos grandes benefícios de uma estrutura de log é ter o contexto fornecido por instâncias separadas do criador de logs - apenas para direcionar as mensagens de log para diferentes destinos. Eu não desistiria disso apenas para salvar uma linha de código (você ainda precisa da importação).
Além disso, isso aumenta a verbosidade no ponto de uso, o que acaba resultando em muito mais pressionamentos de tecla.
Crie seus loggers no ponto de uso
Estou jogando este fora apenas porque elimina a variável. Eu não acho que preciso comentar sobre isso. Embora ele mostre minha técnica preferida para obter uma instância do logger.
Use um pós-processador de bean para injetar o criador de logs
Seu exemplo usa Spring, e o Spring permite conectar o código de inicialização do bean. Você pode criar um pós-processador que inspeciona o bean para uma
logger
variável de membro e cria umaLogger
instância quando encontra uma.Embora esse pós-processador seja apenas algumas dezenas de linhas de código, é outra parte importante do seu aplicativo e, portanto, outra fonte potencial de erros. Eu prefiro ter o menor número possível deles.
Use um mixin
Scala e Groovy fornecem características , que permitem encapsular o comportamento. Um padrão Scala típico é criar uma
Logging
característica e adicioná-la à classe que precisa ser registrada:Infelizmente, isso significa que você precisa mudar de idioma. A menos que você esteja usando o Java 8, nesse caso, você pode criar uma
Logging
interface com um "método padrão":Agora, dentro do seu código de classe, você pode simplesmente usar
Embora fácil, isso tem algumas desvantagens. Por um lado, polui a interface de todas as classes que a usam, porque todos os métodos de interface são públicos. Talvez não seja tão ruim se você o usar apenas para classes instanciadas e injetadas pelo Spring, especialmente se você seguir a separação interface / implementação.
O maior problema é que ele precisa procurar a instância real do criador de logs em todas as chamadas. O que é rápido, mas desnecessário.
E você ainda precisa de uma declaração de importação.
Mover o registrador para uma superclasse
Vou repetir: não acho as definições repetidas do criador de logs detalhadas, mas se você acha que essa é a melhor abordagem para eliminá-las.
Agora suas classes de controlador herdam
AbstractController
e elas têm acesso àlogger
variável. Lembre-se de que você deve colocar a@Controller
anotação na classe concreta.Algumas pessoas acharão isso uma perversão da herança. Tentei acalmá-los nomeando a classe em
AbstractController
vez deAbstractProjectClass
. Você pode decidir por si mesmo se existe ou não um relacionamento.Outras pessoas se oporão ao uso de uma variável de instância em vez de uma variável estática. Os registradores estáticos da IMO tendem a copiar e colar erros, porque você precisa fazer referência explícita ao nome da classe;
getClass()
garante que seu criador de logs esteja sempre correto.fonte
MethodHandles.lookup().lookupClass()
é melhor do queObject.getClass()
?MethodHandles.lookup().lookupClass()
pode ser usado para variáveis estáticas, não é propenso a erros de copiar e colar e é rápido: stackoverflow.com/a/47112323/898747 Isso significa uma entrada extra, mas eu gosto que meus registradores sejam estáticos, pelo menos vale a pena Menção :)Para estender a resposta fornecida por @kdgregory, o Groovy fornece
@Slf4j
(groovy.util.logging.Slf4j
) imediatamente como uma anotação que executa uma transformação AST na classe para aderi-la a um registrador que assume o nome da variávellog
por padrão, se não for especificado.fonte