SLF4J - это слой абстракции Framework Framework, который связывает конкретные фреймворки журнала, такие как Log4J, Logack, Java Logging API и т. Д. SLF4J также имеет свою собственную реализацию по умолчанию, но мы все еще используем SLF4J в качестве уровня абстракции фреймворка для журнала.
Чтобы использовать SLF4J, вы должны включить зависимость от "org.slf4j: slf4j-api".
Простой обзор фасада
SLF4J является типичным применением режима фасада, поэтому, прежде чем говорить о SLF4J, давайте кратко рассмотрим режим фасада.
Фасадный режим, ядро которого состоит в том, что связь с подсистемой должна проводиться через унифицированный объект внешнего вида, что облегчает подсистему в использовании. Структура рисунка витрины используется для представления изображения:
Ядром режима фасада является фасад, то есть объект фасада, а ядро объекта фасада - несколько пунктов:
Вообще говоря, здесь достаточно просто просмотра режима магазина, и вы начнете изучать SLF4J.
Почему мы используем SLF4J
Почему мы используем SLF4J? Например:
Мы используем резерв в нашей собственной системе
Наша система использует A.Jar, а система журналов, используемая в A.Jar, является log4j
Наша система снова использует B.Jar, а система журналов, используемая в B.Jar, SLF4J-Simple
Таким образом, наша система должна поддерживать и поддерживать три фреймворки журнала: Rogack, Log4J и SLF4J-Simple одновременно, что очень неудобно.
Способ решить эту проблему состоит в том, чтобы ввести адаптационный слой, который определяет, какую систему журнала использовать, и абонент должен сделать только только для печати журнала, не заботясь о том, как печатать журнал. SLF4J или Commons-Logging-это слой адаптации, а SLF4J является объектом этого документального исследования.
Из приведенного выше описания мы должны четко знать одну вещь: SLF4J - это просто стандарт журнала, а не конкретная реализация системы ведения журнала. Очень важно понять это предложение. SLF4J упоминает только две вещи:
SLF4J-SIMPLE и REGACKE-это конкретные реализации SLF4J. Log4J не внедряет SLF4J, но есть специальный мост с первым слоем SLF4J-LOG4J12 для реализации SLF4J.
Чтобы лучше понять SLF4J, мы сначала рассмотрим примеры, а затем читаем исходный код. Я считаю, что у читателей будет более глубокое понимание SLF4J.
Пример приложения SLF4J
Как упомянуто выше, прямая/косвенная реализация SLF4J включает SLF4J-Simple, Research, SLF4J-Log4J12. Давайте сначала определим pom.xml и представим соответствующий пакет JAR:
<!-Оригинальный текст: Cangjie в мае http://www.cnblogs.com/xrq730/p/8619156.html-> <project xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: schemalocation = "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.0.0.0.0.0.0. <DOMELVERSION> 4.0.0 </modelVersion> <groupId> org.xrq.log </GroupId> <ArtifactId> log-test </artifactid> <serse> 1.0.0 </version> <Cackaging> jar </packaging> <mame> </name> <hurl> http://maven.apache.orge. <project.build.sourceencoding> utf-8 </project.build.sourceencoding> </свойства> <Depertiencies> <dehyederies> <groupid> junit </GroupId> <artifactid> junit </artifactid> <serview> 4.11 </version> </scope> </scope> </artifactid> <serse> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId> org.slf4j </GroupId> <StrifactId> slf4j-simple </artifactId> <sersion> 1.7.25 </version> </depervice> <dependency> <groupid> log4j </GroupId> <Artifactid> log4j </artifactid> <serse> 1.2.17 </версия> </artifacty> </artifactid> <serse> 1.2.17 </версия> </artifactid> </artifactid> <persion> 1.2.17 <groupId> org.slf4j </GroupId> <ArtifactId> slf4j-log4j12 </artifactid> <sersive> 1.7.21 </version> </dependency> </depertive> </project>
Напишите простой код Java:
@Testpublic void testslf4j () {logger logger = loggerfactory.getLogger (object.class); logger.error ("123"); }Затем мы сначала прокомментируем строки с 30 по 49 Pom.xml выше, то есть мы не вводим какого -либо класса реализации SLF4J и запускаем метод испытания. Давайте посмотрим на вывод консоли как:
Видя выход без каких -либо журналов, это проверяет нашу точку зрения: SLF4J не предоставляет конкретную реализацию журналов, и только SLF4J не может печатать журналы.
Затем откройте аннотацию в классе и запустите метод испытания. Давайте посмотрим на вывод консоли как:
Я видел, что нам просто нужно ввести конкретный класс реализации SLF4J, и мы можем использовать систему журнала для вывода журнала.
Наконец, мы делаем тест. Мы открываем все журналы, вводим журнал-классический, SLF4J-Simple, log4j, запускаем метод испытания, а вывод консоли:
Разница из вышеупомянутого заключается в том, что вы можете выводить журналы, но некоторые журналы тревоги будут выводиться, что призывает нас одновременно ввести несколько реализаций SLF4J, а затем выбрать одну из них в качестве системы журнала, которую мы используем.
Из примера мы можем сделать важный вывод, то есть роль SLF4J: до тех пор, пока весь код использует Facade Object SLF4J, нам не нужно заботиться о ее конкретной реализации. В конце концов, одна конкретная реализация может использоваться во всех местах, а замена и обслуживание очень удобны.
Принцип реализации SLF4J
Я посмотрел пример SLF4J выше, и я буду изучать реализацию SLF4J ниже. Мы сосредоточимся только на ключевом коде.
Использование SLF4J - это предложение, которое остается неизменным в течение всего года, «logger logger = loggerfactory.getLogger (object.class)»; », что показывает, что это для использования LoggerFactory для получения конкретной реализации интерфейса Logger, предоставленного SLF4J. Метод LoggerFactory GetLogger реализован как:
public Static Logger getLogger (class <?> clazz) {logger logger = getLogger (clazz.getName ()); if (detect_logger_name_mismatch) {class <?> AutocomputedCallingClass = util.getCallingClass (); if (AutoComputedCallingClass! = null && noMatchingClasses (clazz, AutoComputedCallingClass)) {util.Report (string.format («Обнаруженное несоответствие имени логика. Util.Report ("See" + logger_name_mismatch_url + "для объяснения"); }} return logger;}Начните с кода из строки 2 и следуйте методу Bind () с LoggerFactory:
Приватный окончательный статический void bind () {try {set <url> staticloggerbinderpathset = null; // Проверка проверки под Android, см. Также // http://jira.qos.ch/browse/slf4j-328 if (! isandroid ()) {staticloggerbinderpathset = findpossiblestaticloggerbinderpathset (); reportMultipleBindingMabIguity (StaticLoggerBinderPathset); } // Следующая строка выполняет связывание staticLoggerbinder.getsingleton (); Initialization_state = успешно_иниализация; reportactualBinding (StaticLoggerBinderPathset); fixsubstituteloggers (); ReplayEvents (); // Выпустить все ресурсы в sup_factory sup_factory.clear (); } catch (noclassdeffounderror ncde) {string msg = ncde.getmessage (); if (messagecontainsorgslf4jimplstaticloggerbinder (msg)) {initiazation_state = nop_fallback_initialization; Util.report («Не удалось загрузить класс /"org.slf4j.impl.staticloggerbinder/». »); Util.Report («Реализация дефолта в реализацию логгера NOPERATION (NOP)»); Util.Report («см.» + No_staticLoggerBinder_url + »для получения дополнительной информации.»); } else {faillbinding (ncde); бросить NCDE; }} catch (java.lang.nosuchmethoderror nsme) {string msg = nsme.getmessage (); if (msg! = null && msg.contains ("org.slf4j.impl.staticloggerbinder.getsingleton ()")) {initiazation_state = faill_initialization; Util.Report ("SLF4J-API 1.6.x (или более поздний) несовместим с этим привязкой."); Util.Report («Ваше привязка - версия 1.5.5 или раньше»); Util.Report («Обновите привязку к версии 1.6.X.»); } бросить nsme; } catch (Exception e) {faillbinding (e); Бросьте новое allodalstateException («неожиданная сбой инициализации», E); }}Строка 7 этого места является ключом, посмотрите на код:
Статический набор <url> findpossiblestaticloggerbinderpathset () {// Использовать набор вместо списка для работы с ошибкой № 138 // LinkedHashset, потому что он сохраняет порядок вставки // во время итерационного набора <url> staticLoggerbinderPathset = new LinkedHashSet <url> (); try {classloader loggerfactoryclassloader = loggerfactory.class.getClassloader (); Перечисление <url> пути; if (loggerfactoryclassloader == null) {paths = classloader.getSystemresources (static_logger_binder_path); } else {paths = loggerfactoryclassloader.getResources (static_logger_binder_path); } while (paths.hasmoreElements ()) {url path = paths.nextelement (); staticloggerbinderpathset.add (path); }} catch (ioException ioe) {util.report ("Ошибка получения ресурсов от пути", ioe); } return staticloggerbinderpathset;}Ключевым моментом этого места является код в строке 12. При получении времени вы перейдете в ClassPath, чтобы найти static_logger_binder_path. Значение static_logger_binder_path - «org/slf4j/Impl/staticloggerbinder.class», то есть все реализации SLF4J, под предоставленным путем пакета JAR должен быть «org/slf4j/inmle/staticLoggerbinder.class». Мы можем взглянуть:
Мы не можем избежать введения нескольких реализаций SLF4J в систему одновременно, поэтому место приемного места является набором. Вы должны отметить, что будут предупреждения, когда вышеупомянутая часть вводит логику, SLF4J-SIMPLE и LOG4J одновременно с демонстрацией:
Это связано с тем, что есть три «org/slf4j/inmp/staticloggerbinder.class», которые существуют. В настоящее время оператор вывода консоли метода отчета MultipleBindingMingMuity:
Private Static void ReportMultipleBindingMabIustuity (set <Url> bindPathset) {if (iSambiguountStaticLoggerBinderPathset (binderPathSet)) {util.Report («Путь класса содержит множественные привязки SLF4J»); for (url path: bindpathset) {util.report («найдено связывание в [" + path + "]"); } Util.Report («См.» + Multiple_bindings_url + »для объяснения.»); }}Тогда пользователи сети могут спросить, что мне делать, если есть три «org/slf4j/Impl/staticloggerbinder.class» в то же время? Прежде всего, определяется, что это не приведет к ошибке в запуске, а во -вторых, во время компиляции компилятор выберет один из Staticloggerbinder.class для привязки.
Наконец, StaticLoggerBinder относительно прост. Различные статичные облогбинды имеют разные реализации getLoggerFactory. После получения iloggerfactory звоните Getlogger и получите конкретный регистратор. Вы можете использовать Logger для вывода журнала.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.