Ваш комментарий говорит, что «многословный» относится к необходимости повторять эту строку кода в каждом классе. Мой первый ответ заключается в том, что добавление двух строк кода (определение переменной плюс оператор импорта) к каждому классу не так уж и сложно. Тем более, что вам нужно только добавить их в классы, которые ведут себя и, следовательно, должны вести журналы. Тем не менее, конкретная строка кода, которую вы используете, подвержена ошибкам копирования-вставки (подробнее об этом позже).
Но, поскольку вы хотите альтернативы, вот несколько, с причинами, по которым вы можете или не захотите их использовать.
Используйте один регистратор для всего приложения
Если вас не волнует, какой класс сообщает, или вы хотите поместить в сообщение весь необходимый контекст, тогда простой одноэлементный регистратор сделает эту работу:
LoggerSingleton.getInstance().debug("MyController is running")
По моему мнению, одно из больших преимуществ каркаса ведения журнала - это наличие контекста, предоставляемого отдельными экземплярами средства ведения журнала - если только для направления сообщений журнала в разные места назначения. Я бы не отказался от этого, просто чтобы сохранить одну строку кода (вам все еще нужен импорт).
Кроме того, это увеличивает многословие в точке использования, что приведет к гораздо большему количеству нажатий клавиш.
Создайте свои регистраторы на месте использования
Я выбрасываю это только потому, что оно исключает переменную. Я не думаю, что мне нужно комментировать это. Хотя это показывает мой предпочтительный метод получения экземпляра регистратора.
Logger.getLogger(getClass()).debug("blah blah blah");
Используйте постпроцессор бина, чтобы внедрить регистратор
В вашем примере используется Spring, а Spring позволяет вам подключиться к коду инициализации компонента. Вы можете создать постпроцессор, который проверяет бин на logger
переменную-член и создает Logger
экземпляр, когда находит его.
Хотя такой постпроцессор занимает всего несколько десятков строк кода, он является еще одной движущейся частью вашего приложения и, следовательно, еще одним потенциальным источником ошибок. Я предпочитаю иметь как можно меньше таких.
Используйте миксин
Scala и Groovy предоставляют черты , которые позволяют вам инкапсулировать поведение. Типичным шаблоном Scala является создание Logging
признака, а затем добавление его в класс, который требует регистрации:
class MyController with Logging
К сожалению, это означает, что вам нужно переключать языки. Если вы не используете Java 8, в этом случае вы можете создать Logging
интерфейс с «методом по умолчанию»:
public interface Logging {
default Logger getLogger() {
return Logger.getLogger(getClass());
}
}
Теперь, внутри вашего кода класса, вы можете просто использовать
getLogger().debug("blah blah blah");
Хотя это легко, у этого есть пара недостатков. С одной стороны, он загрязняет интерфейс каждого класса, который его использует, потому что все методы интерфейса являются открытыми. Возможно, это не так уж и плохо, если вы используете его только для классов, которые создаются и внедряются Spring, особенно если вы используете разделение интерфейса / реализации.
Большая проблема состоит в том, что он должен искать фактический экземпляр регистратора при каждом вызове. Что быстро, но не нужно.
И вам все еще нужно заявление на импорт.
Переместить регистратор в суперкласс
Я повторю: я не нахожу многократные определения логгеров, но если вы это сделаете, я думаю, что это лучший подход к их устранению.
public abstract class AbstractController {
protected Logger logger = Logger.getLogger(getClass());
}
Теперь ваши классы контроллеров наследуются AbstractController
и имеют доступ к logger
переменной. Помните, что вы должны поместить @Controller
аннотацию в конкретный класс.
Некоторые люди сочтут это извращением наследства. Я попытался смягчить их, назвав класс, AbstractController
а не AbstractProjectClass
. Вы сами можете решить, есть ли отношения.
Другие люди будут возражать против использования переменной экземпляра, а не статической переменной. Статические логгеры IMO подвержены ошибкам копирования-вставки, потому что вы должны явно ссылаться на имя класса; getClass()
гарантирует, что ваш регистратор всегда правильно.
getLogger()
имя регистратора, чтобы получить.