The building blocks described previously make Spring a logical choice in many scenarios, from embedded applications that run on resource-constrained devices to full-fledged enterprise applications that use Spring’s transaction management functionality and web framework integration.html
以前描述的構建塊使Spring
成爲許多場景中的邏輯(也就是下意識合理的)選擇,從資源受限的嵌入式程序到成熟的企業應用程序均可以使用 Spring
事務管理功能和 web
框架集成。前端
圖2.2。 典型的完整Spring Web應用程序java
Spring’s declarative transaction management features make the web application fully transactional, just as it would be if you used EJB container-managed transactions. All your custom business logic can be implemented with simple POJOs and managed by Spring’s IoC container. Additional services include support for sending email and validation that is independent of the web layer, which lets you choose where to execute validation rules. Spring’s ORM support is integrated with JPA and Hibernate; for example, when using Hibernate, you can continue to use your existing mapping files and standard Hibernate SessionFactory
configuration. Form controllers seamlessly integrate the web-layer with the domain model, removing the need for ActionForms
or other classes that transform HTTP parameters to values for your domain model.ios
Spring
的聲明式事務管理特性使Web
應用程序具備徹底事務性,就像使用EJB容器管理的事務同樣。 全部的定製業務邏輯均可以經過簡單的POJO
實現,並由Spring
的IoC容器
管理。 其餘服務包括獨立於Web
層的發送電子郵件和驗證的支持,容許你選擇執行驗證規則的位置。 Spring
的ORM
支持集成了JPA
和Hibernate
;(注:和4的文檔比少了JDO
) 例如,當使用Hibernate
時,能夠繼續使用現有的映射文件和標準的Hibernate SessionFactory
配置。 表單控制器將Web
層與域模型無縫集成,從而無需使用ActionForms
或其餘將HTTP
參數轉換爲域模型值的類。(注:也就是這些參數無須單首創建POJO來表達
)git
圖2.3。 Spring中間層使用第三方Web框架web
Sometimes circumstances do not allow you to completely switch to a different framework. The Spring Framework does not force you to use everything within it; it is not anall-or-nothing solution. Existing front-ends built with Struts, Tapestry, JSF or other UI frameworks can be integrated with a Spring-based middle-tier, which allows you to use Spring transaction features. You simply need to wire up your business logic using an ApplicationContext
and use a WebApplicationContext
to integrate your web layer.算法
有時狀況不容許你徹底切換到一個不一樣的框架。 Spring
框架不強迫你使用它裏面的一切; 它不是一個全有或全無的解決方案。 使用Struts
,Tapestry
,JSF
或其餘UI
框架構建的現有前端能夠與基於Spring
的中間層集成,它容許你使用Spring
事務功能。 你只須要使用ApplicationContext
鏈接你的業務邏輯,並使用WebApplicationContext
來集成你的web
層。spring
圖2.4。 遠程使用場景express
When you need to access existing code through web services, you can use Spring’s Hessian-
, Rmi-
or HttpInvokerProxyFactoryBean
classes. Enabling remote access to existing applications is not difficult.apache
當你須要經過Web
服務訪問現有代碼時,可使用Spring
的Hessian-,Rmi-
或HttpInvokerProxyFactoryBean
類(注:此處和4的文檔對比,4使用的是JaxRpcProxyFactory 類
)
。 啓用對現有應用程序的遠程訪問並不困難。
圖2.5。 EJB - 包裝現有POJO
The Spring Framework also provides an access and abstraction layer for Enterprise JavaBeans, enabling you to reuse your existing POJOs and wrap them in stateless session beans for use in scalable, fail-safe web applications that might need declarative security.
Spring Framework
還爲Enterprise JavaBeans
提供了一個 訪問和抽象層,使你能夠重用現有的POJOs
,並將其封裝在無狀態會話bean
中,以用於可能須要聲明性安全性的擴展即有安全故障的Web
應用程序中。
依賴關係管理和命名約定
Dependency management and dependency injection are different things. To get those nice features of Spring into your application (like dependency injection) you need to assemble all the libraries needed (jar files) and get them onto your classpath at runtime, and possibly at compile time. These dependencies are not virtual components that are injected, but physical resources in a file system (typically). The process of dependency management involves locating those resources, storing them and adding them to classpaths. Dependencies can be direct (e.g. my application depends on Spring at runtime), or indirect (e.g. my application depends on commons-dbcp
which depends on commons-pool
). The indirect dependencies are also known as "transitive" and it is those dependencies that are hardest to identify and manage.
If you are going to use Spring you need to get a copy of the jar libraries that comprise the pieces of Spring that you need. To make this easier Spring is packaged as a set of modules that separate the dependencies as much as possible, so for example if you don’t want to write a web application you don’t need the spring-web modules. To refer to Spring library modules in this guide we use a shorthand naming convention spring-*
or spring-*.jar,
where *
represents the short name for the module (e.g. spring-core
, spring-webmvc
, spring-jms
, etc.). The actual jar file name that you use is normally the module name concatenated with the version number (e.g. spring-core-5.0.0.M3.jar).
Each release of the Spring Framework will publish artifacts to the following places:
spring-*-.jar
and the Maven groupId is org.springframework
.So the first thing you need to decide is how to manage your dependencies: we generally recommend the use of an automated system like Maven, Gradle or Ivy, but you can also do it manually by downloading all the jars yourself.
You will find bellow the list of Spring artifacts. For a more complete description of each modules, see Section 2.2, 「Modules」.
依賴管理和依賴注入是不一樣的。爲了讓 Spring
的這些不錯的功能運用到運用程序中(好比依賴注入),你須要導入全部須要的庫(jar文件),而且在編譯、運行的時候將它們放到你的類路徑中。這些依賴關係不是注入的虛擬組件,而是文件系統中的物理資源(一般)。依賴關係管理的過程包括定位這些資源,存儲它們並將它們添加到類路徑。依賴能夠是直接的(例如個人應用程序依賴於Spring
在運行時)或間接(例如個人應用程序依賴於commons-dbcp
,這取決於commons-pool
)。間接依賴性也稱爲「傳遞性」,它是那些最難識別和管理的依賴性。
若是你要使用Spring
,你須要獲得一個包含你須要的Spring
的jar
庫的jar
文件。爲了使這過程更簡單,Spring
被打包爲一組模塊,儘量地分離依賴,因此假如你不想編寫一個web
應用程序,你不須要spring-web
模塊。爲了在本指南中引用Spring
庫模塊,咱們使用一個簡寫命名約定spring- *
或spring - *.jar
,其中*表示模塊的短名稱(例如spring-core,spring-webmvc,spring-jms等)。 )。你使用的實際jar文件名一般是與版本號鏈接的模塊名(例如spring-core-5.0.0.M3.jar
)。
Spring Framework
的每一個版本都會將工件發佈到如下位置:
Maven Central
,它是Maven
查詢的默認存儲庫,不須要使用任何特殊配置。 Spring
依賴的許多通用庫也能夠從Maven Central
得到,Spring
社區的一大部分使用Maven
進行依賴關係管理,因此這對他們很方便。這裏的jars的名字是在spring - * - .jar
和Maven groupId
是org.springframework
。Spring
託管的公共Maven
倉庫中。除了最終GA
版本,此存儲庫還託管開發快照和里程碑。 jar
文件名的格式與Maven Central
相同,所以這是一個有用的地方,可讓Spring
的開發版本與Maven Central
中部署的其餘庫一塊兒使用。此存儲庫還包含捆綁包分發zip
文件,其中包含捆綁在一塊兒的全部Spring jar
以便於下載。因此你須要決定的第一件事是如何管理你的依賴:咱們通常建議使用一個自動化系統,如Maven,Gradle
或Ivy
,但你也能夠手動下載全部的jar
自己。
你會發現下面的Spring
工件列表。有關每一個模塊的更完整的描述,請參見第2.2節「模塊」。
表2.1。 Spring框架組件
GroupId | ArtifactId | Description |
---|---|---|
org.springframework | spring-aop | Proxy-based AOP support 基於代理的AOP支持 |
org.springframework | spring-aspects | AspectJ based aspects 基於AspectJ的切面 |
org.springframework | spring-beans | Beans support, including Groovy Bean支持,包括Groovy |
org.springframework | spring-context | Application context runtime, including scheduling and remoting abstractions 應用程序上下文運行時,包括調度和遠程抽象 |
org.springframework | spring-context-support | Support classes for integrating common third-party libraries into a Spring application context 支持將常見的第三方庫集成到Spring應用程序上下文中的類 |
org.springframework | spring-core | Core utilities, used by many other Spring modules 核心應用程序,由許多其餘Spring模塊使用 |
org.springframework | spring-expression | Spring Expression Language (SpEL) |
org.springframework | spring-instrument | Instrumentation agent for JVM bootstrapping JVM引導的工具代理 |
org.springframework | spring-instrument-tomcat | Instrumentation agent for Tomcat Tomcat的工具代理 |
org.springframework | spring-jdbc | JDBC support package, including DataSource setup and JDBC access support JDBC支持包,包括DataSource設置和JDBC訪問支持 |
org.springframework | spring-jms | JMS support package, including helper classes to send and receive JMS messages JMS支持包,包括用於發送和接收JMS消息的助手類 |
org.springframework | spring-messaging | Support for messaging architectures and protocols 支持消息架構和協議 |
org.springframework | spring-orm | Object/Relational Mapping, including JPA and Hibernate support 對象/關係映射,包括JPA和Hibernate支持 |
org.springframework | spring-oxm | Object/XML Mapping 對象/ XML映射 |
org.springframework | spring-test | Support for unit testing and integration testing Spring components 支持單元測試和集成測試的Spring組件 |
org.springframework | spring-tx | Transaction infrastructure, including DAO support and JCA integration 事務基礎設施,包括DAO支持和集成制定 |
org.springframework | spring-web | Web support packages, including client and web remoting Web支持包,包括客戶端和Web遠程處理 |
org.springframework | spring-webmvc | REST Web Services and model-view-controller implementation for web applications Web應用程序的REST Web服務和模型 - 視圖 - 控制器實現 |
org.springframework | spring-websocket | WebSocket and SockJS implementations, including STOMP support WebSocket和SockJS實現,包括STOMP支持 |
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
,最後使用Ivy
。 在全部狀況下,若是有什麼不清楚,請參考依賴管理系統的文檔,或者查看一些示例代碼 - Spring
自己使用Gradle
在構建時管理依賴關係,咱們的示例主要使用Gradle
或Maven
。
Maven 依賴管理
If you are using Maven for dependency management you don’t even need to supply the logging dependency explicitly. For example, to create an application context and use dependency injection to configure an application, your Maven dependencies will look like this:
若是你使用Maven
進行依賴關係管理,你甚至不須要顯式提供日誌記錄依賴關係。 例如,要建立應用程序上下文並使用依賴注入來配置應用程序,你的Maven
依賴關係將以下所示:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.0.M3</version> <scope>runtime</scope> </dependency> </dependencies>
That’s it. Note the scope can be declared as runtime if you don’t need to compile against Spring APIs, which is typically the case for basic dependency injection use cases.
The example above works with the Maven Central repository. To use the Spring Maven repository (e.g. for milestones or developer snapshots), you need to specify the repository location in your Maven configuration. For full releases:
就是這樣。 注意,若是不須要針對Spring API
進行編譯,範圍(scope
)能夠聲明爲運行時(runtime
),這一般是基本依賴注入使用用例。
上面的示例使用Maven Central
存儲庫。 要使用Spring Maven
存儲庫(例如,用於里程碑或開發人員快照),你須要在Maven
配置中指定存儲庫位置。 完整版本:
<repositories> <repository> <id>io.spring.repo.maven.release</id> <url>http://repo.spring.io/release/</url> <snapshots><enabled>false</enabled></snapshots> </repository> </repositories>
里程碑:
<repositories> <repository> <id>io.spring.repo.maven.milestone</id> <url>http://repo.spring.io/milestone/</url> <snapshots><enabled>false</enabled></snapshots> </repository> </repositories>
And for snapshots: 以及快照:
<repositories> <repository> <id>io.spring.repo.maven.snapshot</id> <url>http://repo.spring.io/snapshot/</url> <snapshots><enabled>true</enabled></snapshots> </repository> </repositories>
It is possible to accidentally mix different versions of Spring JARs when using Maven. For example, you may find that a third-party library, or another Spring project, pulls in a transitive dependency to an older release. If you forget to explicitly declare a direct dependency yourself, all sorts of unexpected issues can arise.
To overcome such problems Maven supports the concept of a "bill of materials" (BOM) dependency. You can import the spring-framework-bom
in your dependencyManagement
section to ensure that all spring dependencies (both direct and transitive) are at the same version.
在使用Maven
時,可能會意外混合不一樣版本的Spring JAR
。 例如,你可能會發現第三方庫或另外一個Spring
項目將傳遞依賴項拉入舊版本。 若是你忘記本身顯式聲明一個直接依賴,可能會出現各類意想不到的問題。
爲了克服這種問題,Maven
支持「物料清單」(BOM
)依賴的概念。 你能夠在dependencyManagement
部分中導入spring-framework-bom
,以確保全部spring
依賴項(直接和可傳遞)具備相同的版本。
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>5.0.0.M3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
An added benefit of using the BOM is that you no longer need to specify the <version>
attribute when depending on Spring Framework artifacts:
使用 BOM
後,當依賴 Spring Framework
組件後,無需再指定<version>
屬性
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependencies>
經過Gradle 作依賴管理
To use the Spring repository with the Gradle build system, include the appropriate URL in the repositories
section:
要將Spring
存儲庫與Gradle
構建系統一塊兒使用,請在repositories
部分中包含相應的URL
:
repositories { mavenCentral() // and optionally... maven { url "http://repo.spring.io/release" } }
You can change the repositories
URL from /release
to /milestone
or /snapshot
as appropriate. Once a repository has been configured, you can declare dependencies in the usual Gradle way:
你能夠根據須要將 repositories
中URL從/ release
更改成/ milestone
或/ snapshot
。 一旦配置了 repositories
,就能夠按照一般的Gradle
方式聲明依賴關係:
dependencies { compile("org.springframework:spring-context:5.0.0.M3") testCompile("org.springframework:spring-test:5.0.0.M3") }
Ivy 依賴管理
If you prefer to use Ivy to manage dependencies then there are similar configuration options.
To configure Ivy to point to the Spring repository add the following resolver to your ivysettings.xml
:
若是你喜歡使用Ivy來管理依賴,那麼有相似的配置選項。
要配置Ivy
指向Spring
存儲庫,請將如下解析器添加到你的ivysettings.xml
:
<resolvers> <ibiblio name="io.spring.repo.maven.release" m2compatible="true" root="http://repo.spring.io/release/"/> </resolvers>
You can change the root
URL from /release/
to /milestone/
or /snapshot/
as appropriate.
Once configured, you can add dependencies in the usual way. For example (in ivy.xml
):
你能夠根據須要將root
URL從/ release /
更改成/ milestone /
或/ snapshot /
。
配置後,你能夠按照一般的方式添加依賴關係。 例如(在ivy.xml
中):
<dependency org="org.springframework" name="spring-core" rev="5.0.0.M3" conf="compile->runtime"/>
Although using a build system that supports dependency management is the recommended way to obtain the Spring Framework, it is still possible to download a distribution zip file.
Distribution zips are published to the Spring Maven Repository (this is just for our convenience, you don’t need Maven or any other build system in order to download them).
To download a distribution zip open a web browser to http://repo.spring.io/release/org/springframework/spring and select the appropriate subfolder for the version that you want. Distribution files end -dist.zip
, for example spring-framework-{spring-version}-RELEASE-dist.zip. Distributions are also published for milestones and snapshots.
儘管使用支持依賴性管理的構建系統是獲取Spring Framework
的推薦方式,但仍然能夠下載分發zip
文件。
分發zip
是發佈到Spring Maven
倉庫(這只是爲了咱們的方便,你不須要Maven
或任何其餘構建系統爲了下載它們)。
要下載分發zip
,請打開Web瀏覽器到http://repo.spring.io/release/org/springframework/spring,而後爲所需的版本選擇適當的子文件夾。 分發文件結尾是 -dist.zip
,例如spring-framework- {spring-version} -RELEASE-dist.zip
。 還分發了里程碑和快照的分發。
日誌
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 application work. 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
的一個很是重要的依賴,由於a)
它是惟一的強制性的外部依賴,b)
每一個人都喜歡從他們使用的工具看到一些輸出,和c)
Spring集成了許多其餘工具,日誌依賴性的選擇。應用程序開發人員的目標之一一般是在整個應用程序的中心位置配置統一日誌記錄,包括全部外部組件。這就更加困難,由於它可能已經有太多選擇的日誌框架。
Spring
中的強制性日誌依賴性是Jakarta Commons Logging API(JCL)
。咱們編譯JCL
,咱們也使JCL Log
對象對於擴展Spring
框架的類可見。對於用戶來講,全部版本的Spring都使用相同的日誌庫很重要:遷移很容易,由於即便使用擴展Spring
的應用程序也保持向後兼容性。咱們這樣作的方式是使Spring中的一個模塊顯式地依賴commons-logging(JCL的規範實現),而後使全部其餘模塊在編譯時依賴它。若是你使用Maven爲例,並想知道你在哪裏選擇對commons-logging
的依賴,那麼它是從Spring
,特別是從中央模塊稱爲spring-core
(關於此處,理解就好,翻譯的不到位
)。
關於commons-logging
的好處是,你不須要任何其餘東西來就能讓你的應用程序工做。它有一個運行時發現算法,該算法在衆所周知的classpath
路徑下尋找其餘日誌框架,並使用它認爲是合適的(或者你能夠告訴它,若是你須要)。若是沒有其餘可用的,你能夠從JDK
(java.util.logging
或簡稱JUL
)得到漂亮的查看日誌。你應該會發現,你的Spring
應用程序在大多數狀況下能夠很好地工做和記錄到控制檯,這很重要。
不使用 Commons Logging
Unfortunately, the runtime discovery algorithm in commons-logging
, while convenient for the end-user, 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
:
spring-core
module (as it is the only module that explicitly depends on commons-logging
)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:
不幸的是,公共日誌中的運行時發現算法雖然對於終端用戶方便,可是是有問題的。 若是咱們能夠時光倒流並啓動Spring
做爲一個新項目,它將使用不一樣的日誌依賴關係。 第一個選擇多是用於Java
的簡單日誌外觀(SLF4J),它也被許多其餘工具用於Spring
在其應用程序中使用。
基本上有兩種方法關閉commons-logging
:
1.從spring-core
模塊中排除依賴性(由於它是惟一顯式依賴commons-logging
的模塊)
2.依賴於一個特殊的commons-logging
依賴,用一個空jar替換庫(更多細節能夠在 SLF4J FAQ中找到)
要排除commons-logging
,請將如下內容添加到你的dependencyManagement
部分:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.0.M3</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
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.
如今這個應用程序運行不了,由於沒有在類路徑上實現JCL API
,因此要解決它須要提供一個新的。 在下一節中,咱們將向你展現如何使用SLF4J
提供JCL
的替代實現。
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
更高效,由於它使用編譯時綁定,而不是其集成的其餘日誌框架的運行時發現。這也意味着你必須更明確地瞭解你想在運行時發生什麼,並聲明它或相應地配置它。 SLF4J
提供了對許多常見日誌框架的綁定,所以你一般能夠選擇一個已經使用的綁定,並綁定到配置和管理。
SLF4J
提供對許多常見日誌框架(包括JCL
)的綁定,而且它也作了反向工做:充當其餘日誌框架與其自身之間的橋樑。所以,要在Spring中使用SLF4J
,須要使用SLF4J-JCL
橋替換commons-logging
依賴關係。一旦你這樣作,那麼來自Spring
內部的日誌調用將被轉換爲對SLF4J API
的日誌調用,所以若是應用程序中的其餘庫使用該API,那麼你有一個地方能夠配置和管理日誌記錄。
常見的選擇多是將Spring
橋接到SLF4J
,而後提供從SLF4J
到Log4J
的顯式綁定。你須要提供4個依賴(並排除現有的commons-logging
):橋樑,SLF4J API
,綁定到Log4J
和Log4J
實現自己。在Maven
,你會這樣作
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.0.M3</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.5.8</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.5.8</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.8</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> </dependency> </dependencies>
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-logging
表現的更加的好,特別是當它運行在在一個嚴格的容器中像OSGi
平臺。 據稱,還有一個性能優點,由於綁定是在編譯時,而不是運行時。
SLF4J
用戶中更常見的選擇是使用較少的步驟和生成較少的依賴關係,它是直接綁定到Logback
。 這消除了額外的綁定步驟,由於Logback
直接實現SLF4J
,因此你只須要依賴於兩個不是四個庫(jcl-over-slf4j
和logback
)。 若是你這樣作,你可能還須要從其餘外部依賴(不是Spring
)中排除slf4j-api
依賴,由於你只須要在類路徑上有一個版本的API
。
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:
許多人使用Log4j做爲日誌框架用於配置和管理目的。 它是高效的和成熟的,事實上,這是咱們在運行時使用時,咱們構建和測試Spring
。 Spring
還提供了一些用於配置和初始化Log4j
的實用程序,因此它在一些模塊中對Log4j
有一個可選的編譯時依賴。
要使Log4j
使用默認的JCL
依賴(commons-logging
),全部你須要作的是將Log4j
放在類路徑上,併爲它提供一個配置文件(在類路徑的根目錄下的log4j.properties
或log4j.xml
)。 因此對於Maven
用戶,這是你的依賴性聲明:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.0.M3</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> </dependency> </dependencies>
And here’s a sample log4j.properties for logging to the console:
下面是一個簡單的log4j.properties
的實例,用於將日誌打印到控制檯:
log4j.rootCategory=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n log4j.category.org.springframework.beans.factory=DEBUG
Many people run their Spring applications in a container that itself provides an implementation of JCL. IBM Websphere Application Server (WAS) is the archetype. This often causes problems, and unfortunately there is no silver bullet solution; simply excluding commons-logging
from your application is not enough in most situations.
To be clear about this: the problems reported are usually not with JCL per se, or even with commons-logging
: rather they are to do with binding commons-logging
to another framework (often Log4J). This can fail because commons-logging
changed the way they do the runtime discovery in between the older versions (1.0) found in some containers and the modern versions that most people use now (1.1). Spring does not use any unusual parts of the JCL API, so nothing breaks there, but as soon as Spring or your application tries to do any logging you can find that the bindings to Log4J are not working.
In such cases with WAS the easiest thing to do is to invert the class loader hierarchy (IBM calls it "parent last") so that the application controls the JCL dependency, not the container. That option isn’t always open, but there are plenty of other suggestions in the public domain for alternative approaches, and your mileage may vary depending on the exact version and feature set of the container.
許多人在一個容器中運行他們的Spring
應用程序,該容器自己提供了JCL
的實現。 IBM Websphere
應用服務器(WAS
)就是一個例子。這經常致使問題,不幸的是沒有一個一勞永逸解決方案;在大多數狀況下,只是從你的應用程序中排除commons-logging
是不夠的。
要明確這一點:報告的問題一般不是JCL
自己,或者甚至與commons-logging
:而是他們要綁定到另外一個框架(一般Log4J)的公共日誌。這可能會失敗,由於commons-logging
改變了在一些容器中發現的舊版本(1.0)和大多數人如今使用的現代版本(1.1)之間執行運行時發現的方式。 Spring
不使用JCL API
的任何不常見的模塊,因此沒有什麼問題出現,但一旦Spring
或你的應用程序試圖作任何日誌記錄,你能夠發現綁定的Log4J
不工做了。
在這種狀況下,使用WAS
,最容易作的事情是反轉類加載器層次結構(IBM稱之爲「父最後一個」),以便應用程序控制JCL
依賴關係,而不是容器。該選項並不老是開放的,但在公共領域有許多其餘建議替代方法,你的里程可能會根據容器的確切版本和功能集而有所不一樣。
以爲看着彆扭的能夠查看本人Gitbook :https://muyinchen.gitbooks.io/spring-framework-5-0-0-m3/content/