1. 程式人生 > >2.1 Spring的日誌依賴

2.1 Spring的日誌依賴

Spring Dependencies and Depending on Spring
Although Spring provides integration and support for a huge range of enterprise and other external tools, it intentionally keeps its mandatory dependencies to an absolute minimum: you shouldn’t have to locate and download (even automatically) a large number of jar libraries in order to use Spring for simple use cases. For basic dependency injection there is only one mandatory external dependency, and that is for logging (see below for a more detailed description of logging options).
Next we outline the basic steps needed to configure an application that depends on Spring, first with Maven and then with Gradle and finally using Ivy. In all cases, if anything is unclear, refer to the documentation of your dependency management system, or look at some sample code - Spring itself uses Gradle to manage dependencies when it is building, and our samples mostly use Gradle or Maven.
儘管spring提供企業級和其他工具的打範圍整合和支援,它有意將強制依賴性保持為絕對最小值,你不應該找到並下載(甚至自動)大量JAR庫,以便使用Spring進行簡單使用。例如對於基本的依賴注入,只有一個強制外部依賴項,即用於日誌記錄(請參閱下面的日誌選項的詳細描述)。
下面我們列出了配置spring應用程式基本的步驟。分別介紹maven,Gradle,ILY.在任何情況下,如果有什麼不清楚的話,請參考對你的依賴管理systemlogging選項檔案)。或者看一些簡單的樣例程式碼,spirng自身構建時候使用Gradle管理依賴,並且我們的樣例大多使用Gradle和maven.
這裡寫圖片描述


這裡寫圖片描述

Logging
Logging is a very important dependency for Spring because a) it is the only mandatory external dependency, b) everyone likes to see some output from the tools they are using, and c) Spring integrates with lots of other tools all of which have also made a choice of logging dependency. One of the goals of an application developer is often to have unified logging configured in a central place for the whole application, including all external components. This is more difficult than it might have been since there are so many choices of logging framework.
The mandatory logging dependency in Spring is the Jakarta Commons Logging API (JCL). We compile against JCL and we also make JCL Log objects visible for classes that extend the Spring Framework.
It’s important to users that all versions of Spring use the same logging library: migration is easy because backwards compatibility is preserved even with applications that extend Spring. The way we do this is to make one of the modules in Spring depend explicitly on commons-logging (the canonical implementation of JCL), and then make all the other modules depend on that at compile time. If you are
using Maven for example, and wondering where you picked up the dependency on commons-logging,then it is from Spring and specifically from the central module called spring-core.The nice thing about commons-logging is that you don’t need anything else to make your applicationwork. It has a runtime discovery algorithm that looks for other logging frameworks in well known places。on the classpath and uses one that it thinks is appropriate (or you can tell it which one if you need to).If nothing else is available you get pretty nice looking logs just from the JDK (java.util.logging or JUL for short). You should find that your Spring application works and logs happily to the console out of the box in most situations, and that’s important.
日誌
日誌是Spring唯一強制的外部依賴項。每個人都喜歡工具會打印出一些東西,Spring集成了一些其它的工具,所有這些工具都有日誌依賴。應用開發人員的目標之一是通常需要在應用中心位置配置統一日誌記錄。包括所有的外部元件。自從有了很多日誌選擇框架以來,這個問題就變得困難了。
在Spring中唯一的強制日誌依賴是JCL,我們編譯在JCL也使JCL日誌物件類擴充套件Spring框架可見.所有版本的Spring使用統一的日誌類庫對於使用者是很重要的;程式遷徙很容易,因為
即使是擴充套件Spring的應用程式,也可以保留向後相容性,我們這樣做的方式是讓Spring中的一個模組顯式地依賴於commons-logging(規範繼承JCL),並且讓那個其他的模組在編譯期間依賴它。如果你是用maven,並且會好奇怎樣獲得commons-logging依賴,然後是Spring特別是核心模組Spring-core
使用commons-logging的好處是你不需要其他額外的東西來讓你的應用程式工作。它在執行期間有一個查詢演算法用來在類路徑的合適位置下尋找其他日誌框架並且在恰當的地方使用(或者你可以告訴它你想要哪個),如果沒有吧找到其他的日誌框架你將會發現它使用的JDK自帶的JUL API,Spring還是會正常的工作和列印日誌到控制檯,這是很重要的。


Not Using Commons Logging
Unfortunately, the runtime discovery algorithm in commons-logging, while convenient for the enduser, is problematic. If we could turn back the clock and start Spring now as a new project it would use a different logging dependency. The first choice would probably be the Simple Logging Facade for Java( SLF4J), which is also used by a lot of other tools that people use with Spring inside their applications.
There are basically two ways to switch off commons-logging:
1. Exclude the dependency from the spring-core module (as it is the only module that explicitly
depends on commons-logging)
2. Depend on a special commons-logging dependency that replaces the library with an empty jar
(more details can be found in the SLF4J FAQ)
To exclude commons-logging, add the following to your dependencyManagement section:
這裡寫圖片描述


Now this application is probably broken because there is no implementation of the JCL API on the classpath, so to fix it a new one has to be provided. In the next section we show you how to provide an alternative implementation of JCL using SLF4J as an example.
不使用Commons Logging
不幸的是,commons-logging的執行期間發現演算法,在方便後臺程式設計師的同時也是有很多問題的。如果我們撤銷並且現在新建一個Spring專案,它將會使用一個不同的日誌依賴。第一個不同的選擇將是SLF4J,也深受Spring的大多使用者的歡迎。
這裡有兩種基礎方式去切換commons-logging
1.在spring-core模組中去除這個依賴(因為它是唯一顯式的模組。依賴於commons-logging)
2.選擇一個特定commons-logging依賴用空jar包去替換掉這個類庫
如果想去掉commons-logging,將下面的依賴管理部分加入到maven中
現在這個應用程式可能執行不了因為在類路徑下沒有JCL API的實現,所以下面提供了一個修復它的例子。在下面的部分,我們將用SLF4J提供一個可選的JCL實現作為例子。

Using SLF4J
SLF4J is a cleaner dependency and more efficient at runtime than commons-logging because it uses compile-time bindings instead of runtime discovery of the other logging frameworks it integrates. This also means that you have to be more explicit about what you want to happen at runtime, and declare it or configure it accordingly. SLF4J provides bindings to many common logging frameworks, so you can
usually choose one that you already use, and bind to that for configuration and management. SLF4J provides bindings to many common logging frameworks, including JCL, and it also does the reverse: bridges between other logging frameworks and itself. So to use SLF4J with Spring you need to replace the commons-logging dependency with the SLF4J-JCL bridge. Once you have done that then logging calls from within Spring will be translated into logging calls to the SLF4J API, so if other
libraries in your application use that API, then you have a single place to configure and manage logging.A common choice might be to bridge Spring to SLF4J, and then provide explicit binding from SLF4J to Log4J. You need to supply 4 dependencies (and exclude the existing commons-logging): the bridge。
the SLF4J API, the binding to Log4J, and the Log4J implementation itself. In Maven you would do that like this
SLF4J是一個比commons-logging在執行期間更加高效簡潔的依賴因為它使用了編譯期間繫結而不是在執行期間發現其它自身整合的日誌框架的演算法。這也意味著你必須更明確地知道你想要在執行時發生什麼。並且有根據的宣告和配置它。SLFJ提供很多常用日誌框架的繫結,所以你可以選擇一個你準備要使用的,並且繫結配置並且管理。
SLF4J提供許多常用日誌框架的繫結,包括JCL,並且它也在相反的方向上做了一些改進:連線自身和其他的日誌框架,所以對於在Spring中使用SLF4J的時候你需要用SLF4J-JCL連線橋替換調commons-logging依賴。一旦你做了上述步驟,Spring日誌呼叫將會使用SLF4J API.所以如果其他的類庫在你的應用程式中使用了這個API,你將會用一些簡單的方式去配置和管理日誌。
一個常見的選擇肯呢個是Spring和SLF4J橋,然後提供顯式繫結到從slf4j到log4j,在maven下這樣繫結SLF4J和Log4J
這裡寫圖片描述
That might seem like a lot of dependencies just to get some logging. Well it is, but it is optional, and it should behave better than the vanilla commons-logging with respect to classloader issues, notably if you are in a strict container like an OSGi platform. Allegedly there is also a performance benefit because the bindings are at compile-time not runtime. A more common choice amongst SLF4J users, which uses fewer steps and generates fewer dependencies, is to bind directly to Logback. This removes the extra binding step because Logback implements SLF4J directly, so you only need to depend on two libraries not four ( jcl-over-slf4j and logback). If you do that you might also need to exclude the slf4j-api dependency from other external
dependencies (not Spring), because you only want one version of that API on the classpath.
看起來這麼多的依賴僅僅只是獲得日誌依賴。但是這是可選的,和commons-loggging相比它應該有更好的表現,值得注意的是如果您處於像OSGi平臺這樣的嚴格容器中。據稱這樣會有一些平臺好處因為它實在編譯期間繫結而不是執行期間的。
更常見的是slf4j使用者之間的選擇,它使用較少的步驟,生成更少依賴,是直接繫結到logback。這去除了額外的繫結步驟因為Logback直接實現了SLF4J。所以你可以依賴兩個類庫(jcl-over-slf4j and logback)而不是4個。如果你這樣做,你可能也需要排除的是slf4j API依賴從其他外部依賴關係(不是Spring),因為你只想要一個版本的API的類路徑。

Using Log4J
Many people use Log4j as a logging framework for configuration and management purposes. It’s efficient and well-established, and in fact it’s what we use at runtime when we build and test Spring. Spring also provides some utilities for configuring and initializing Log4j, so it has an optional compile-time dependency on Log4j in some modules. To make Log4j work with the default JCL dependency ( commons-logging) all you need to do is put Log4j on the classpath, and provide it with a configuration file ( log4j.properties or log4j.xml in the root of the classpath). So for Maven users this is your dependency declaration:
這裡寫圖片描述
在執行期間容器和原生的JCL
許多人在提供JCL實現的容器裡執行Spring應用程式。IBM的Webspsphere(WAS)是一個典型。這將會導致一些問題。不幸的是沒有特別出色的解決方案:在大多情況下在你的應用程式下去除commons-logging依賴已經不能滿足。
更清楚的講:報告的問題通常不是JCL本身或者是commons-logging本身:而他們結合commons-logging到另一個框架(通常是log4j)這可能會失敗,因為公共日誌記錄改變了它們之間執行時發現的方式。舊版本(1)在一些容器和大多數人使用的現代版本中找到。Spring不使用任何的JCL不尋常的部分API,所以那裡沒有任何問題,但只要你用Spring繫結Log4j試圖做任何記錄,可以發現Log4j不工作.
在這種情況下,最容易做的事情是顛倒類裝入器層次結構(IBM稱之為“父級”)。最後”),應用程式控制JCL的依賴,不是容器.這種選擇並不總是公開,但在公共領域有許多其他建議可供選擇,您的里程可能因容器的精確版本和特性集而異。