Как простое добавление slf4j в pom.xml обертывает log4j?

Из того, что я видел в примерах файлов spring pom.xml, видно, что они добавляют несколько записей для slf4j и log4j, и каким-то образом, когда вы используете log4j в своем весеннем приложении, он будет обернут библиотекой slf4j.

Может кто-нибудь объяснить мне, как это волшебным образом происходит?


person codecompleting    schedule 29.12.2011    source источник


Ответы (2)


Spring по-прежнему использует commons-logging для всех внутренних журналов (обратная совместимость). Если вы хотите использовать какую-либо другую платформу ведения журналов (log4j), вам необходимо связать вызовы из commons logging с выбранной вами платформой. В противном случае вам придется поддерживать несколько конфигураций ведения журнала.

slf4j выступает в качестве простого фасада для различных фреймворков ведения журналов (jul, log4j, jcl, logback) и позволяет подключать нужную фреймворк ведения журналов во время развертывания.

Вместо использования реализации фреймворка ведения журнала, навязанного сторонней инфраструктурой, вы предоставляете реализацию моста slf4j's, которая действует как реальная вещь, но на самом деле просто перенаправляет вызовы ведения журнала на slf4j или его конкретную привязку.

Раздел ведения журнала Maven pom.xml обычно выглядит так:

<!-- remove the real commons-logging from classpath -->
<!-- declare as provided or exclude from spring jars -->
<dependency>
    <artifactId>commons-logging</artifactId>
    <groupId>commons-logging</groupId>
    <version>1.0</version>
    <scope>provided</scope>
</dependency>

<!-- add slf4j interfaces to classpath -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.6.4</version>
    <scope>compile</scope>
</dependency>

<!-- add commons logging to slf4j bridge to classpath --> 
<!-- acts as jcl but routes commons-logging calls to slf4j -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.6.4</version>
    <scope>runtime</scope>
</dependency>

<!-- add log4j binding to classpath -->
<!-- routes slf4j calls to log4j -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.4</version>
    <scope>runtime</scope>
</dependency>

<!-- add log4j to classpath -->
<!-- does the logging -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.16</version>
</dependency>

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

См. перейдите по ссылкам для получения дополнительной информации.

person Bruno Dević    schedule 29.12.2011
comment
Хотя этот ответ довольно хорош, в нем есть одна неточность: SLF4J не соединен с ведением журналов общих ресурсов, зависимость jcl-over-slf4j содержит повторную реализацию API ведения журналов общих ресурсов. Вот почему очень важно убедиться, что ведение журнала общих ресурсов не находится в вашем пути к классам, потому что два модуля используют одно и то же имя пакета (по необходимости) и, следовательно, катастрофически конфликтуют друг с другом. Контекстный модуль Spring содержит зависимость от spring-core, которая содержит зависимость от commons-logging, поэтому вы должны принять активные меры, чтобы предотвратить это при использовании Spring. - person Periata Breatta; 30.10.2016
comment
Также немного чище специально исключить зависимость от ведения журналов общих ресурсов в Spring, что вы можете сделать, как описано в эту статью на веб-сайте Spring, вместо того, чтобы сообщать Maven, что она уже есть в вашем пути к классам (что на самом деле является хаком). - person Periata Breatta; 30.10.2016

slf4j — это API ведения журналов, который ничего не делает, просто набор интерфейсов. log4j — это система регистрации с конкретными классами. существует библиотека slf4j-log4j, которая использует log4j в качестве бэкенда для API slf4j.

Некоторые проекты явно зависят от log4j, они вызывают конкретные классы. Таким образом, вы не можете использовать другой бэкенд (например, logback, j.u.l, apache commons или что-то еще) для своего проекта, который вы мудро сделали, используя только API slf4j.

Существует хитрость, позволяющая заменить классы log4j фиктивной реализацией (мостом), которая просто перенаправляет все звонки на sl4j. В maven вы просто объявляете зависимость с очень высоким номером версии, и этот макет считается ультрасовременной библиотекой log4j.

person kan    schedule 29.12.2011
comment
поэтому во время выполнения он использует внедрение зависимостей? еще запутался извините. - person codecompleting; 29.12.2011
comment
Нет, знаток <dependency>. Может я не понимаю вопроса? Можете ли вы уточнить это? - person kan; 29.12.2011