Должен ли регистратор быть закрытым статическим или нет - PullRequest
95 голосов
/ 02 октября 2010

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

    protected Log log = new Log4JLogger(aClass.class);

или

    private static Log log = new Log4JLogger(aClass.class);

Какой из них следует использовать? Какие плюсы и минусы у обоих?

Ответы [ 4 ]

92 голосов
/ 02 октября 2010

Преимущество нестатической формы заключается в том, что вы можете объявить ее в (абстрактном) базовом классе следующим образом, не беспокоясь о том, что будет использовано правильное имя класса:

protected Log log = new Log4JLogger(getClass());

Однако его недостатком, очевидно, является то, что для каждого экземпляра класса будет создан новый экземпляр журнала. Это само по себе может быть не дорого, но добавляет значительных накладных расходов. Если вы хотите избежать этого, вы должны вместо этого использовать форму static. Но его недостаток, в свою очередь, заключается в том, что вы должны объявлять его в каждом отдельном классе и следить за тем, чтобы в каждом классе использовалось правильное имя класса при создании логгера, поскольку getClass() нельзя использовать в статическом контексте. Однако в средней IDE вы можете создать шаблон автозаполнения для этого. Например. logger + ctrl+space.

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

protected Log log = LogManager.getLogger(getClass());
43 голосов
/ 03 марта 2011

Раньше я думал, что все логгеры должны быть статичными;однако эта статья на wiki.apache.org поднимает некоторые важные проблемы с памятью, касающиеся утечек из загрузчика классов.Объявление логгера как статического предотвращает сбор мусора в классе (и связанных с ним загрузчиках классов) в контейнерах J2EE, которые используют общий загрузчик классов.Это приведет к ошибкам PermGen, если вы повторно развернете свое приложение достаточно раз.

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

15 голосов
/ 03 октября 2010

Самое важное отличие состоит в том, как это влияет на ваши файлы журналов: в какой категории идут журналы?

  • При первом выборе журналы подкласса попадают в категорию суперкласса.Это кажется мне нелогичным.
  • Существует вариант вашего первого случая:

    Защищенный журнал Журнал = новый Log4JLogger (getClass ());

    В этом случае в вашей категории журнала указывается, над каким объектом работал код, который был зарегистрирован.

  • При вашем втором выборе (приватная статика) категория журнала - это класс, который содержит код журнала.Поэтому обычно класс, который делает то, что регистрируется.

Я бы настоятельно рекомендовал этот последний вариант.Он имеет следующие преимущества по сравнению с другими решениями:

  • Существует прямая связь между журналом и кодом.Легко узнать, откуда пришло сообщение журнала.
  • Если кому-то приходится настраивать уровни ведения журнала (что делается для каждой категории), обычно это происходит потому, что они заинтересованы (или не заинтересованы) в некоторых конкретных сообщенияхнаписанный определенным классом.Если категория не является классом, пишущим сообщения, настроить уровни сложнее.
  • Вы можете войти в статические методы
  • Регистраторы должны быть только инициализированы (или просмотрены)один раз для каждого класса, то есть при запуске, а не для каждого созданного экземпляра.

У него также есть недостатки:

  • Он должен быть объявлен в каждом классе, где вы регистрируете сообщения(без повторного использования регистраторов суперкласса).
  • При инициализации регистратора необходимо правильно указать имя класса.(Но об этом позаботятся хорошие IDE).
3 голосов
/ 02 октября 2010

Использовать инверсию управления и передать регистратор в конструктор. Если вы создадите регистратор внутри класса, у вас будут чертовы времена с вашими юнит-тестами. Вы пишете юнит-тесты?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...