O logger deve ser declarado estático ou não? Normalmente, tenho visto dois tipos de declaração para um logger:
log de log protegido = novo Log4JLogger (aClass.class);
ou
log de log estático privado = new Log4JLogger (aClass.class);
Qual deve ser usado? quais são os prós e contras de ambos?
static
é uma referência por classe. não estático é uma referência por instância (+ inicialização). Portanto, em alguns casos, o último vem com um impacto significativo na memória se você tiver toneladas de instâncias. Nunca use o não estático em um objeto frequente . Eu sempre uso a versão estática. (que deve ser maiúsculoLOG
)private static final Log log
minúsculas. O logger não é uma constante, o logger é um objeto final estático (que pode sofrer mutação). Pessoalmente, sempre usologger
.Respostas:
A vantagem da forma não estática é que você pode declará-la em uma classe base (abstrata) como a seguir, sem se preocupar se o nome de classe correto será usado:
No entanto, sua desvantagem é obviamente que uma nova instância do logger será criada para cada instância da classe. Isso pode não ser caro por si só, mas adiciona uma sobrecarga significativa. Se quiser evitar isso, use o
static
formulário. Mas sua desvantagem é que você precisa declará-lo em cada classe individual e tomar cuidado em cada classe para que o nome de classe correto seja usado durante a construção do logger porquegetClass()
não pode ser usado em contexto estático. No entanto, no IDE comum, você pode criar um modelo de preenchimento automático para isso. Por exemplo,logger
+ctrl+space
.Por outro lado, se você obtiver o logger de uma fábrica que, por sua vez, pode armazenar em cache os loggers já instanciados, o uso da forma não estática não adicionará muito overhead. Log4j, por exemplo, tem um
LogManager
para esse propósito.fonte
abstract Log getLogger();
na classe abstrata. Implemente este método, retornando o logger estático para a instância particular. Adicioneprivate final static Log LOG = LogManager.getLogger(Clazz.class);
ao seu modelo de classe IDE.protected Logger log = LoggerFactory.getLogger(getClass());
Eu costumava pensar que todos os loggers deveriam ser estáticos; no entanto, este artigo em wiki.apache.org traz à tona algumas questões importantes sobre memória, relacionadas a vazamentos de carregador de classe. Declarar um logger como estático evita que a classe declarante (e carregadores de classe associados) seja coletado como lixo em contêineres J2EE que usam um carregador de classe compartilhado. Isso resultará em erros de PermGen se você reimplantar seu aplicativo vezes suficientes.
Eu realmente não vejo nenhuma maneira de contornar esse problema de vazamento do carregador de classe, além de declarar os registradores como não estáticos.
fonte
A diferença mais importante é como isso afeta seus arquivos de log: em qual categoria vão os logs?
Existe uma variante do seu primeiro caso:
log de log protegido = new Log4JLogger (getClass ());
Nesse caso, sua categoria de log diz em qual objeto o código que fez o log estava trabalhando.
Em sua segunda opção (private static), a categoria de log é a classe que contém o código de log. Normalmente a classe que está fazendo a coisa que está sendo registrada.
Eu recomendaria fortemente essa última opção. Ele tem essas vantagens, em comparação com as outras soluções:
Também tem desvantagens:
fonte
Use a inversão de controle e passe o logger para o construtor. Se você criar o logger dentro da classe, terá muito trabalho com seus testes de unidade. Você está escrevendo testes de unidade, não é?
fonte