Статьи

Настройка Maven для использования SLF4J

В основном я пишу статьи по двум причинам: чтобы понять что-то новое для меня или задокументировать то, что я регулярно должен объяснять другим. Эта статья определенно относится ко второй категории: чтобы отпраздновать новую версию Logback 1.0.0 , я решил раз и навсегда записать, как правильно использовать SLF4J с Maven, поскольку, похоже, в этом нет недостатка в вопросах. ,

основы

Основой SLF4J является наличие двух отдельных компонентов, одного API и одной реализации. Это означает, что ваш код должен зависеть исключительно от API, поэтому реализация может быть изменена по вашему усмотрению. Помните, что разделение кода от реализаций путем введения интерфейса должно быть вашей первой заботой: на уровне библиотеки это роль API.

Это легко сделать так в вашем POM:

<project ...>
  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.6.4</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <scope>runtime</scope>
      <version>1.0.0</version>
    </dependency>
  <dependencies>
</project>

Область выполнения не позволяет нам использовать классы реализации Logback при кодировании, что обеспечивает разделение.

Примечание: если вы используете родительский POM для вашего проекта (потому что у вас есть модули ), само собой разумеется, что вышеупомянутые зависимости должны быть в разделе dependencyManagement.

Bridging

Поскольку приложение с только функциями ведения журнала немного ограничено, весьма вероятно, что нам понадобятся другие зависимости. Конечно, некоторые из этих зависимостей могут использовать другие каркасы журналирования, такие как Commons Logging или Log4J .

Например, Spring использует Commons Logging: таким образом, журналы, созданные нашим приложением, будут использовать logback, тогда как журналы, созданные Spring, будут использовать Commons Logging. Эта стратегия требует двух разных файлов конфигурации (а также знания обоих), что не очень интуитивно понятно. Более того, это было бы неудобно при чтении двух потоков из двух разных источников. Обратите внимание, что это можно смягчить, используя цели ведения журналов, отличные от файлов (которых я еще не видел).

К счастью, SLF4J предоставляет мостовые компоненты, которые позволяют напрямую подключать сторонние API-вызовы к SLF4J. Для Spring это означает удаление всех зависимостей в Commons Logging и замену их единственной зависимостью от моста Commons Logging до SLF4.

<project ...>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.0.0</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>3.0.0</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.0</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.6.2</version>
    </dependency>
  <dependencies>
</project>

Как и в предыдущем разделе, вы должны использовать

Примечание: хотя эти знания ни в коем случае не являются необходимыми, знайте, что, поскольку API и реализация являются пакетами вместе в commons-logging.jar, мост jcl-over-slf4.jar полностью заменяет классы API, предоставляемые Commons Logging. Это означает, что вы не должны иметь оба JAR в вашем classpath!

Поиск проблемы

Помните правило горцев: «может быть только один». В этом случае на пути к классам может быть доступна только одна реализация, так как SLF4J использует поставщик сервисов Java . В этом случае SLF4J отобразит предупреждение «Обнаружено несколько привязок на пути к классам» и использует первое найденное (сначала на пути к классам). Поскольку классовые пути заказаны Maven, маловероятно, что это будет то, что мы хотим. Таким образом, позаботьтесь о том, чтобы не помещать slf4j-simple в область тестирования вместе с logback, или будьте готовы столкнуться с неопределенными побочными эффектами.

Чтобы идти дальше:

 

От http://blog.frankel.ch/configuring-maven-to-use-slf4j