官方文档地址:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#spring-introduction
作者列表
Rod Johnson , Juergen Hoeller , Keith Donald , Colin Sampaleanu , Rob Harrop , Thomas Risberg , Alef Arendsen , Darren Davison , Dmitriy Kopylenko , Mark Pollack , Thierry Templier , Erwin Vervaet , Portia Tung , Ben Hale , Adrian Colyer , John Lewis , Costin Leau , Mark Fisher , Sam Brannen , Ramnivas Laddad , Arjen Poutsma , Chris Beams , Tareq Abedrabbo , Andy Clement , Dave Syer , Oliver Gierke , Rossen Stoyanchev , Phillip Webb , Rob Winch , Brian Clozel , Stephane Nicoll , Sebastien Deleuze
4.3.8.RELEASE
版权所有© 2004-2016
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
只要您不对这些副本收取任何费用,并且进一步规定,每个副本都包含本版权声明,无论是以印刷版还是电子版分发,本文档的副本可供您自己使用并分发给他人。
第一部分 Spring框架概述
Spring Framework是一个轻量级解决方案,可以一站式的构建企业级应用程序。但是,Spring是模块化的,允许使用部分所需的部件,而不使用其余的部件。可以在任何Web框架上使用控制反转(IoC),也可以仅仅是用 Hibernate集成代码或者JDBC抽象层。Spring框架支持声明式事务管理,通过RMI或Web服务远程访问您的逻辑,以及用于持久存储数据的各种选项。它提供了一个全功能的MVC框架,使您能够将AOP透明地集成到您的软件中。
Spring被设计为非侵入性的,这意味着您的域逻辑代码通常不依赖于框架本身。在集成层(如数据访问层)中,会存在一些依赖同时依赖于数据访问技术和Spring,但是这些依赖可以很容易地从代码库中分离出来。
本文档是Spring Framework功能的参考指南。如果您对本文档有任何要求,意见或问题,请将其发布在 用户邮件列表中。或者在StackOverflow上询问框架本身的问题(请参阅https://spring.io/questions)。
1. Spring入门
本参考指南提供有关Spring框架的详细信息。它为所有功能提供了全面的文档,以及Spring所提供的基本概念(如“依赖注入”)的背景知识。
如果您刚开始使用Spring,可以通过创建一个 Spring Boot的基本应用程序来开始使用Spring框架。Spring Boot提供了一种快速(有选择的)的方式创建一个基于生产的Spring应用程序。它基于Spring框架,有利于配置的设定,从而使得程序尽快开始运行。
您可以使用start.spring.io生成一个基本项目,或按照“入门指南”中的一个指南,例如开始创建RESTful 项目入门 。除了易于理解以外,这些指南非常任务化,大部分都是基于Spring Boot。他们还涵盖了Spring解决方案中您可能想要考虑的其他项目。
2. Spring框架介绍
Spring 框架是一个Java平台,为开发Java应用程序提供全面的基础设施支持。Spring很好的处理了基础设施,因此可以专注于应用程序开发。
Spring使您能够从“简单的Java对象”(POJO)构建应用程序,并将企业服务非侵入式应用于POJO。此功能适用于Java SE编程模型以及完整和部分的Java EE。
那么作为应用程序开发人员,我们可以从Spring平台中得到什么呢:
- 使Java方法在数据库事务中执行,而不必处理事务API。
- 使本地Java方法成为HTTP端点,而无需处理Servlet API。
- 使本地Java方法成为消息处理程序,而无需处理JMS API。
- 使本地Java方法成为管理操作,而无需处理JMX API。
2.1依赖注入和控制反转
一个Java应用程序,从受限制的嵌入式应用到n层的服务端应用,典型地是由相互合作的对象组成的,因此,一个应用程序中的对象是相互依赖的。
虽然Java平台提供了丰富的应用程序开发功能,但它缺乏将基本构建块组织成一个连贯的整体的方法,将该任务留给架构师和开发人员。可以使用工厂模式Factory
,抽象工厂模式Abstract Factory
,创建者模式Builder
,装饰者模式Decorator
和服务定位器模式Service Locator
等设计模式来构成构成应用程序的各种类和对象实例,这些模式是简单的:因为框架给出这些设计模式名称对应的最佳实践,以及什么样的模式,应用于哪里,它解决的问题等等。这些设计模式都是最佳实践的结晶,所以你应该在你的应用程序中使用它们。
Spring的控制反转解决了上述问题,它提供了一种正式的解决方案,你可以把不相干组件组合在一起,从而组成一个完整的可以使用的应用。Spring根据设计模式编码出了非常优秀的代码,所以可以直接集成到自己的应用中。因此,大量的组织机构都使用Spring来保证应用程序的健壮性和可维护性。
**背景**
Martin Fowler 在2004年在他的网站上提出了关于控制反转(IoC)的问题“The question is, what aspect of control are [they] inverting?”。
Fowler 由此建议重新命名这个原则,使其更加清晰明了,并提出依赖注入。
2.2框架模块
Spring框架由组织成约20个模块的功能组成。这些模块分为核心容器Core Container
,数据访问/集成Data Access / Integration
,Web
,AOP
(面向对象编程),Instrumentation
,消息处理Messaging
和测试Test
,如下图所示。
以下部分列出了每个功能对应的模块及主题,并且提供功能的Artifact name
。Artifact name
与依赖关系管理工具中使用的Artifact name
相关联。
2.2.1核心集装箱Core Container
核心容器spring-core
, spring-beans
,spring-context
,spring-context-support
,和spring-expression
(Spring表达式语言)多个模块组成。
spring-core
和spring-beans
模块是Spring框架的基础,包括IoC控制反转和依赖注入。而BeanFactory
是工厂模式的复杂实现。它消除了对编程单例的需要,并允许将依赖关系的配置和规范与实际程序逻辑分离。
Spring上下文模块spring-context
建立在Spring核心Core
和Bean
模块之上:它以一个JNDI注册的方式去访问一个对象。上下文模块Context
继承自Beans
模块,并增加了对国际化的支持(例如使用资源束),事件传播,资源加载以及透明创建上下文对象,例如Servlet容器。Context
模块还支持Java EE功能,如EJB,JMX(Java Management Extensions
,即Java管理扩展)和基本远程处理。ApplicationContext
接口是上下文模块的关键点。spring-context-support
支持将常见的第三方库集成到Spring应用程序上下文缓存(EhCache,Guava,JCache),邮件(JavaMail),调度(CommonJ,Quartz)和模版引擎(FreeMarker,JasperReports,Velocity)中
spring-expression
模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP 2.1规范中规定的统一表达语言(统一EL)的扩展。该语言支持设置和获取属性值,属性分配,方法调用,访问数组,集合和索引器的内容,逻辑和算术运算符,命名变量以及从Spring的IoC容器中以名称检索对象。它还支持列表投影和选择以及常见列表聚合。
2.2.2 AOP和检测Instrumentation
spring-aop
模块提供了一个符合AOP联盟标准的面向对象的编程实现,允许您定义方法拦截器和切入点,用于分离实现可分离的功能代码。使用源级别元数据功能,您还可以以类似于.NET属性的方式将行为信息合并到代码中。
独立的spring-aspects
模块提供与AspectJ
(一个面向切面的框架)的集成。
spring-instrument
模块提供了对检测类的支持和用于特定的应用服务器的类加载器的实现。spring-instrument-tomcat
模块包含用与Tomcat的Spring测试代理。
2.2.3消息传递
Spring 4包含的spring-messaging
是从Spring集成项目中抽象出来的模块,例如Message
、MessageChannel
、MessageHandler
,和其他基于消息的基础应用程序。该模块还包括一组用于将消息映射到方法的注释,类似于基于Spring MVC注释的编程模型。
2.2.4数据访问/集成
数据访问/集成层由JDBC,ORM,OXM,JMS和事务模块组成。
spring-jdbc
模块提供了一个JDBC抽象层,可以省去冗长的JDBC编码和解析数据库供应商特定错误代码的需要。
spring-tx
模块支持编程式事务和声明式事务,可用于实现了特定接口的类和所有的POJO对象。
(译者注:编程式事务需要自己写beginTransaction()、commit()、rollback()等事务管理方法,声明式事务是通过注解或配置由spring自动处理,编程式事务粒度更细)
spring-orm
模块为流行的对象关系映射API提供集成层 ,包括JPA, JDO和Hibernate。使用spring-orm模块,您可以将所有这些O/RMapping框架与Spring提供的所有其他功能结合使用,例如前面提到的简单的声明式事务管理功能。
spring-oxm
模块提供了一个支持Object/XML映射实现(如JAXB,Castor,XMLBeans,JiBX和XStream)的抽象层。
spring-jms
模块(Java消息服务)包含用于生成和消费消息的功能。自Spring Framework 4.1以来,它提供了与spring-messaging
模块的集成。
2.2.5 网络Web
网络层由spring-web
,spring-webmvc
,spring-websocket
,和 spring-webmvc-portlet
模块组成。
spring-web
模块提供基本的面向Web的集成功能,例如多部分multipart
文件上传功能,使用Servlet监听器初始化IoC容器等。它还包含一个HTTP客户端和Spring的远程支持的Web相关部分。
spring-webmvc
模块(也称为Web-Servlet
模块)包含用于Web应用程序的Spring的模型视图控制器model-view-controller
(MVC)和REST Web Services实现。Spring MVC架构提供了领域模型代码和Web表单之间的分离,并与Spring框架的其他所有功能集成。
spring-webmvc-portlet
模块(也称为Web-Portlet
模块)提供了在Portlet环境中使用的MVC实现,并反映了基于Servlet的spring-webmvc
模块的功能。
2.2.6测试
spring-test
模块支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。它提供一致性加载和Spring应用程序上下文ApplicationContext,以及缓存这些上下文。它还提供可用于独立测试代码的模拟对象的功能。
2.3使用场景
之前描述的构建块使Spring成为许多场景中的逻辑选择,不管是在资源受限设备上运行的嵌入式应用程序,或者使用Spring的事务管理功能和Web框架集成的企业级应用程序。
Spring的声明式事务管理功能使Web应用程序完全事务性,就像使用EJB容器管理的事务一样。所有您的定制业务逻辑都可以使用简单的POJO实现,并由Spring的IoC容器进行管理。附加服务包括支持发送电子邮件和独立于Web层的验证,可让您选择执行验证规则的位置。Spring的ORM支持与JPA,Hibernate和JDO集成; 例如,当使用Hibernate时,您可以继续使用现有的映射文件和标准的Hibernate SessionFactory
配置。表单控制器将Web层与域模型无缝集成,移除了将ActionFormsHTTP
参数转换为域模型的值或其他类的需求。
有时情况不允许你完全切换到不同的框架。Spring框架不会强制使用其内的所有模块; 这不是一个要么全有,要么全没有的解决方案。使用Struts
,Tapestry
,JSF
或其他UI框架构建的现有前端可以与基于Spring的中间层集成,从而允许您使用Spring事务功能。您只需使用一个应用程序上下文对象ApplicationContext
连接您的业务逻辑,并使用WebApplicationContext
来集成Web层。
当你需要通过Web服务来访问现有的代码,你可以使用Spring框架的的Hessian-
,Burlap-
,Rmi-
或JaxRpcProxyFactory
类。启用对现有应用程序的远程访问并不困难。
Spring框架还为Enterprise JavaBeans
提供了一个访问抽象层,使您能够重用现有的POJO,并将其包装在无状态会话bean
中,以用于可能需要声明式安全性的可扩展的,故障安全的Web应用程序。
2.3.1依赖管理和命名约定
依赖关系管理和依赖注入是不同的。为了将Spring的这些不错的功能引入到应用程序中(如依赖注入),您需要组装所有需要的库(jar文件),并在运行时和编译时将它们导入到类路径中。这些依赖关系不是注入的虚拟组件,而是文件系统中的物理资源(通常情况下如此)。依赖关系管理的过程包括定位这些资源,存储它们并将其添加到类路径中。依赖关系可以是直接的(例如,我的应用程序在运行时依赖Spring)或间接(例如我的应用程序取决于commons-dbcp
哪个依赖于commons-pool
)。间接依赖关系也被称为“传递性”,它们是最难识别和管理的依赖关系。
如果你要使用Spring框架,你需要获得一个包含你所需要的Spring块的jar库的副本。为了使获取更容易,Spring框架被打包为一组尽可能分离依赖关系的模块,例如,如果您不想编写Web应用程序,则不需要spring-web
模块。本指南中,我们使用速记命名约定到Spring库模块spring-*
或 spring-*.jar
,其中*代表该模块的短名称(例如spring-core
, spring-webmvc
, spring-jms
等)。您使用的实际jar文件名通常是用模块名称与版本号连接(例如spring-core-4.3.8.RELEASE.jar
)。
Spring框架的每个版本都会将包Artifact
发布到以下位置:
-
Maven Central
Maven中央仓库
它是Maven查询的默认存储库,不需要任何特殊配置。Spring的许多常见的库也可以从Maven Central
获得,Spring框架的大部分功能使用Maven进行依赖关系管理,所以这是很方便的。jar包的名称是spring-*-<version>.jar
,Maven库中groupId是org.springframework
。 - 在专门用于放置Spring框架的公共Maven存储库中。除了最终的GA版本,该存储库还有开发版
snapshots
和里程碑版本milestones
。jar包命名格式与Maven Central的格式相同,这样放置也是很有用的,可以将Spring的开发版本snapshots
与在Maven Central中部署的其他库一起使用。该存储库还包含压缩后的zip文件,其中包含所有Spring框架用到的jar包,压缩在一起以便于下载。
因此您需要确定的第一件事是如何管理您的依赖关系:我们通常建议使用像Maven
,Gradle
或Ivy
这样的自动化系统,但您也可以通过自己下载所有的jar包来手动进行操作。
下面你将会看到Spring工件的列表。有关每个模块的更完整的描述,请参见第2.2节“框架模块”。
表2.1. Spring框架工件
GroupId | ArtifactId | Description |
---|---|---|
org.springframework | spring-aop | 基于代理的AOP |
org.springframework | spring-aspects | 基于切面的AspectJ |
org.springframework | spring-beans | Bean支持, 包括Groovy |
org.springframework | spring-context | 运行时上下文,包括调度和远程调用抽象 |
org.springframework | spring-context-support | 包含用于集成第三方库到Spring上下文的类 |
org.springframework | spring-core | 核心库,被许多其它模块使用 |
org.springframework | spring-expression | Spring表达式语言 |
org.springframework | spring-instrument | JVM引导的检测代理 |
org.springframework | spring-instrument-tomcat | tomcat的检测代理 |
org.springframework | spring-jdbc | JDBC支持包,包括对数据源设置和JDBC访问支持 |
org.springframework | spring-jms | JMS支持包,包括发送和接收JMS消息的帮助类 |
org.springframework | spring-messaging | 消息处理的架构和协议 |
org.springframework | spring-orm | 对象关系映射,包括对JPA和Hibernate支持 |
org.springframework | spring-oxm | 对象XML映射 |
org.springframework | spring-test | 单元测试和集成测试组件 |
org.springframework | spring-tx | 事务基础,包括对DAO的支持及JCA的集成 |
org.springframework | spring-web | web支持包,包括客户端及web远程调用 |
org.springframework | spring-webmvc | REST web服务及web应用的MVC实现 |
org.springframework | spring-webmvc-portlet | 用于Portlet环境的MVC实现 |
org.springframework | spring-websocket | WebSocket和SockJS实现,包括对STOMP的支持 |
Spring的依赖和被依赖
虽然Spring为大量企业和其他外部工具提供集成和支持,但它有意将其强制性依赖性保持在最低限度:您不必因为想要使用Spring框架搭建简单的用例,而去定位和下载(甚至自动)大量的jar库。对于基本依赖注入,只有一个强制性的外部依赖关系,也就是用于日志记录(有关日志记录选项的更详细描述,请参见下文)。
接下来,我们概述了配置依赖于Spring的应用程序所需的基本步骤,首先是使用Maven,然后使用Gradle,最后使用Ivy。在任何情况下,如果不清楚,请参阅依赖关系管理系统的文档,或查看一些示例代码 - Spring本身在构建时使用Gradle来管理依赖关系,而且我们的示例主要使用Gradle或Maven。
Maven依赖管理
如果您使用Maven进行依赖关系管理,则甚至不需要显式提供记录依赖关系。例如,要创建应用程序上下文并使用依赖注入来配置应用程序,您的Maven依赖项将如下所示:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.8.RELEASE</version>
<scope>runtime</scope>
</dependency>
</dependencies>
就这样,注意如果不需要编译Spring API,可以把scope声明为runtime,这是依赖注入使用的典型案例。
上面的示例使用Maven中央仓库,如果使用Spring的Maven仓库(例如,里程碑版本milestones
或开发快照版本snapshots
),需要在Maven配置中指定仓库位置。
release版本:
<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>
开发快照版本
<repositories>
<repository>
<id>io.spring.repo.maven.snapshot</id>
<url>http://repo.spring.io/snapshot/</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Maven“物料清单式”依赖
使用Maven时,可能会意外混合不同版本的Spring JAR包。例如,您可能从第三方库中下载,或另一个Spring项目存在旧的版本依赖。如果您忘记自己明确声明直接依赖,可能会出现各种意外问题。
为了克服这些问题,Maven支持“物料单”(BOM)依赖的概念。您可以导入spring-framework-bom
到您的dependencyManagement
部分,以确保所有Spring依赖(直接和传递)都是相同的版本。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
使用BOM的一个额外的好处是,您不再需要在引用Spring框架工件时去指定<version>
属性了:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
Gradle依赖关系管理
为了在Gradle构建系统中使用Spring仓库,需要在repositories
部分包含合适的URL:
repositories {
mavenCentral()
// and optionally...
maven { url "http://repo.spring.io/release" }
}
可以酌情把repositories
URL中的/release
修改为/milestone
或/snapshot
。一旦仓库配置好了,就可以按Gradle的方式声明依赖关系了。
dependencies {
compile("org.springframework:spring-context:4.3.8.RELEASE")
testCompile("org.springframework:spring-test:4.3.8.RELEASE")
}
Ivy依赖关系管理
使用Ivy管理依赖关系有相似的配置选项。
在ivysettings.xml
中添加resolver配置使Ivy指向Spring仓库:
<resolvers>
<ibiblio name="io.spring.repo.maven.release"
m2compatible="true"
root="http://repo.spring.io/release/"/>
</resolvers>
可以酌情把root
URL中的/release
修改为/milestone
或/snapshot
。
一旦配置好了,就可以按照惯例添加依赖了(在ivy.xml
中):
发行版的Zip文件
虽然使用支持依赖管理的构建系统是获取Spring框架的推荐方法,但是也支持通过下载Spring的发行版zip文件获取。
发行版zip文件发布在了Sprng的Maven仓库上(这只是为了方便,不需要额外的Maven或其它构建系统去下载它们)。
浏览器中打开http://repo.spring.io/release/org/springframework/spring,并选择合适版本的子目录,就可以下载发行版的zip文件了。发行文件以-dist.zip
结尾,例如,spring-framework-{spring-version}-RELEASE-dist.zip。发行文件也包含里程碑版本和快照版本。
2.3.2 日志记录
日志记录是Spring非常重要的功能依赖,因为a) 它是唯一的强制性外部依赖关系,b) 每个人都喜欢看到他们使用的工具的一些输出,c) Spring集成了许多其他工具,它们都选择了日志依赖关系。
应用程序开发人员的目标之一通常是将统一的日志记录配置在整个应用程序的中央位置,包括所有外部组件。这比以前更加困难,因为日志框架有太多选择。
Spring中的强制性日志依赖关系是Jakarta Commons Logging API
(JCL)。我们针对JCL进行编译,我们也使JCL Log对象对于扩展Spring Framework的类可见。对于用户来说,所有版本的Spring都使用相同的日志库,这样做非常重要,这样做以后迁移很简单,因为即使扩展Spring的应用程序仍然保留向后兼容性。我们这样做的方法是使Spring中的一个模块明确地依赖于commons-logging
(JCL的规范实现),然后在编译时使所有其他模块依赖于它。例如,如果您使用Maven,并且想知道您在哪里选择对commons-logging
的依赖关系,那么它来自Spring,特别是来自中央模块spring-core
。
使用commons-logging
更为方便的是,你不需要任何其他东西来使你的应用程序工作。它具有运行时发现算法,可以在配置的类路径中查找其他日志记录框架,并使用它认为合适的记录框架(或者您可以告诉它需要哪一个)。如果没有其他可用的,您可以从JDK(简称java.util.logging
或JUL)获得非常实用的日志。由此你可以发现,在大多数情况下,你的Spring程序都可以正常的工作,并且能够输出信息到控制台,这是很重要的。
使用Log4j 1.2或者2.x
Log4j 1.2在此期间是EOL。此外,Log4j 2.3是最新的Java 6兼容版本,较新的Log4j 2.x版本需要Java 7+版本。
许多人使用Log4j作为配置和管理目的的日志框架。它高效且成熟,实际上在我们在构建Spring时,它是在运行时使用的。Spring还提供了一些用于配置和初始化Log4j的实用程序,因此它在某些模块中对Log4j具有可选的编译时依赖性。
要使Log4j 1.2使用默认的JCL依赖项(commons-logging
),您需要做的就是将Log4j放在类路径上,并为其提供配置文件(log4j.properties
或log4j.xml
在类路径的根目录中)。所以对于Maven用户来说,这是你的依赖声明:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
下面是输出日志到控制台的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
要使用Log4j 2.X与JCL,你需要做的就是把Log4j放到在类路径下,并为其提供一个配置文件(log4j2.xml
,log4j2.properties
或其他支持的配置格式)。对于Maven用户,所需的最小依赖关系是:
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
如果您还希望启用SLF4J委托Log4j,例如默认使用SLF4J的其他库,则还需要以下依赖关系:
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
以下是使出日志到控制台的示例配置文件log4j2.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework.beans.factory" level="DEBUG"/>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
避免使用Commons Logging
不幸的是,标准commons-logging
API中的运行时发现算法对于最终用户来说方便,但是可能是有问题的。如果你想避免JCL的标准查找,基本上有两种方法来关闭它:
- 从
spring-core
模块中排除依赖关系(因为它是唯一明确依赖的模块commons-logging
)
- 取决于一个特殊的
commons-logging
依赖关系,用空的jar代替库(更多的细节可以在SLF4J FAQ中找到 )
要排除公共记录,请将以下内容添加到您的dependencyManagement
部分:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.8.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
现在这个应用程序目前被破坏,因为在类路径中没有实现JCL API,所以要修复它,必须提供一个新的JCL API。在下一节中,我们向您展示如何使用SLF4J提供JCL的替代实现。
使用SLF4J与Log4j或Logback
Java简单日志模式(SLF4J)是Spring常用的其他库流行API。它通常配合SLF4J API本地化的Logback
使用。
SLF4J提供了绑定到许多常见的日志记录框架的功能,包括Log4j,并且它也可以完成相反的工作:其他日志记录框架和其自身之间的桥梁。所以要使用SLF4J与Spring,您需要使用SLF4J-JCL桥替代commons-logging
的依赖关系配置。一旦完成,那么在Spring中记录调用将被转换为对SLF4J API的记录调用,因此如果应用程序中的其他库使用该API,那么就会有一个单独的地方来配置和管理日志记录。
常见的选择可能是将Spring链接到SLF4J,然后提供从SLF4J到Log4j的显式绑定。您需要提供几个依赖关系(并排除现有的commons-logging
):JCL桥接器,SLF4j绑定到Log4j,以及Log4j提供器。在Maven中,你可以这样做
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.8.RELEASE</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.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
SLF4J用户更为常见的选择,是使用较少的步骤以及生成更少的依赖关系,就是直接绑定到Logback。因为直接的logback实现SLF4J,也会消除多余的绑定步骤,所以你只需要仅仅依靠两个库,即jcl-over-slf4j
和logback
):
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
使用JUL(java.util.logging
)
只要在类路径中没有检测到Log4j,Commons Logging都会默认委派java.util.logging
。所以没有什么特别的依赖关系:在一个独立的应用程序(在JDK级别使用自定义或默认的JUL设置)中只要在使用Spring是没有配置外部依赖,日志输出就会使用java.util.logging
,或应用程序服务器的日志系统(和它的系统级JUL设置)。
Commons登录WebSphere
Spring应用程序可以在本身提供JCL实现的容器上运行,例如IBM的WebSphere Application Server
(WAS)。这并不会导致问题本身,而是导致需要了解的两种不同的场景:
在“父级第一”ClassLoader授权模型(WAS中的默认值)中,应用程序将始终选择Commons Logging提供的服务器版本,委托给WAS记录子系统(实际上基于JUL)。JCL的应用程序提供的变量,无论是标准的Commons Logging还是JCL-over-SLF4J
桥,都将被有效地被忽略,以及任何本地包含的日志提供程序。
使用“父进程”委托模式(常规Servlet容器中的默认值,WAS上的显式配置选项),在您的应用程序中,将提取应用程序提供的Commons Logging变量,使您能够设置本地包含的日志提供程序,例如Log4j或Logback。在没有本地日志提供程序的情况下,默认情况下,常规Commons Logging将委托给JUL,有效地记录到WebSphere的日志记录子系统,同“父级第一”方案一致。
总而言之,我们建议将“Spring”应用程序部署在“父进程”模式中,因为它自然地允许本地提供程序以及服务器的日志子系统。