Есть ли какая-либо причина для использования приватной финальной статики вместо LogBack Logger? - PullRequest
24 голосов
/ 25 ноября 2011

При создании экземпляра Logger в Spring Controller, есть ли причина объявить его как static final ?Logger не используется вне MyController.class.Я видел оба примера в использовании, но не могу понять, почему я должен использовать один или другой.

private Logger logger = LoggerFactory.getLogger(MyController.class);

против

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

Ответы [ 4 ]

42 голосов
/ 25 ноября 2011

Лично я пользуюсь

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

Основным преимуществом этого является то, что я могу вырезать и вставить это в новые классы без необходимости менять имя класса.

Относительно того, должны ли они быть статическими, см. Должны ли члены класса Logger быть объявлены как статические? с веб-сайта slf4j, на котором написано:

Раньше мы рекомендовали объявлять члены регистраторов переменными экземпляра вместо статических. После дальнейшего анализа мы больше не рекомендуем один подход над другим.

Взято с этой страницы:

Преимущества объявления логгеров как статических

  1. распространенная и устоявшаяся идиома
  2. меньше ресурсов процессора: регистраторы извлекаются и назначаются только один раз при инициализации класса хостинга
  3. меньше накладных расходов памяти: объявление журнала будет использовать одну ссылку на класс

Недостатки объявления логгеров как статических

  1. Для библиотек, совместно используемых приложениями, невозможно использовать селекторы репозитория. Следует отметить, что если привязка SLF4J и базовый API поставляются с каждым приложением (не совместно используемым приложениями), то у каждого приложения все равно будет своя собственная среда ведения журналов.
  2. не подходит для МОК

Преимущества объявления регистраторов в качестве переменных экземпляра

  1. Возможно использовать селекторы репозитория даже для библиотек, совместно используемых приложениями. Однако селекторы репозитория работают только в том случае, если базовая система ведения журналов является logback-classic. Селекторы репозитория не работают для комбинации SLF4J + log4j.
  2. IOC-дружеский

Недостатки объявления регистраторов в качестве переменных экземпляра

  1. Менее распространенная идиома, чем объявление логгеров в качестве статических переменных
  2. более высокая загрузка ЦП: регистраторы извлекаются и назначаются для каждого экземпляра класса хостинга
  3. более высокая нагрузка на память: объявление журнала будет использовать одну ссылку на экземпляр класса хостинга

Объяснение

Статические члены регистратора стоят одну ссылку на переменную для всех экземпляров класса, тогда как член регистратора экземпляра будет стоить ссылку на переменную для каждого экземпляра класса. Для простых классов, создаваемых тысячи раз, может быть заметная разница.

Однако более поздние системы ведения журнала, например, log4j или logback, поддерживают отдельный контекст средства ведения журнала для каждого приложения, работающего на сервере приложений. Таким образом, даже если на сервере развернута одна копия log4j.jar или logback-classic.jar, система ведения журналов сможет различать приложения и предлагать отдельную среду ведения журналов для каждого приложения.

Точнее говоря, каждый раз, когда средство ведения журнала извлекается путем вызова метода LoggerFactory.getLogger (), базовая система ведения журнала будет возвращать экземпляр, подходящий для текущего приложения. Обратите внимание, что в том же приложении, получающем регистратор по заданному имени, всегда будет возвращаться один и тот же регистратор. Для данного имени другой регистратор будет возвращен только для разных приложений.

Если регистратор статичен, то он будет извлечен только один раз, когда класс хостинга будет загружен в память. Если класс хостинга используется только в одном приложении, беспокоиться не о чем. Однако, если класс хостинга совместно используется несколькими приложениями, все экземпляры общего класса войдут в контекст приложения, в результате которого первый класс был загружен в память, что вряд ли будет ожидаемым пользователем поведением.

Дополнительную информацию см. На этой странице.

3 голосов
/ 25 ноября 2011
Поле

Just private будет инициализировано для каждого экземпляра вашего класса.Однако поле private static будет инициализировано один раз для каждого класса.

В случае регистратора наиболее вероятно (зависит от реализации ведения журнала), в обоих случаях вы получите один и тот же экземпляр регистратора и не будете использоватьзаметно больший объем памяти.Но все равно LoggerFactory.getLogger будет вызываться с каждым созданным вами объектом.

1 голос
/ 25 ноября 2011

Да; так что для класса есть только один регистратор, а не один на экземпляр.

В любом случае это приватно, поэтому использование его вне класса не имеет к этому никакого отношения - это не то, что static final делает.

0 голосов
/ 19 декабря 2011

Мне просто любопытно, что эта строка:

private Logger logger = LoggerFactory.getLogger(MyController.class);

Это:

LoggerFactory.getLogger(MyController.class) 

или:

LoggerFactory.getLogger(MyController.class.getName());

Потому что первый вернется«класс» перед настоящим именем:

class com.example.MyController (instead of com.example.MyController) 
...