文章目录
说明
翻译自:
http://docs.spring.io/spring/docs/5.0.0.M4/spring-framework-reference/htmlsingle/
Part I. Spring框架概览
Spring Framework是一种轻量级的解决方案,是构建你的企业级应用程序的潜在一站式解决方案。 尽管如此,Spring是模块化的,允许你只使用你需要的那些部分,而不必引入其他的。 你可以使用IoC容器,任何Web框架在顶部(只是底层用Spring框架,比如ssh,中间那层用了Spring),但你也可以只使用Hibernate集成代码或JDBC抽象层。 Spring框架支持声明式事务管理,通过RMI或Web服务远程访问你的逻辑,以及用于持久存储数据的各种选项。 它提供了一个全功能的MVC框架,并使你能够将AOP透明地集成到你的软件中。
Spring设计为非侵入式的,这意味着你所写的逻辑代码通常没有对框架本身的依赖。 在你的集中处理层(例如数据访问层)中,将存在对数据访问技术和Spring库的一些依赖。 但是,应该很容易将这些依赖关系与其余代码库隔离开。
本文档是Spring Framework特性的参考指南。 如果你对本文档有任何要求,意见或问题,请将其张贴在用户邮件列表中。 框架本身的问题应该在StackOverflow(请参阅https://spring.io/questions)。
1. Spring入门
本参考指南提供了有关Spring框架的详细信息。 它提供了所有功能的全面文档,以及Spring所拥有的基本概念(例如“依赖注入”)的一些背景知识。
如果你刚刚开始使用Spring,你可能想要通过创建一个基于Spring Boot的应用程序来开始使用Spring Framework。 Spring Boot提供了一种快速(和建议性)的方式来创建基于生产环境的Spring应用程序。 它是基于Spring框架,喜欢约定的配置,并且旨在让你快速启动和运行。
你可以使用start.spring.io来生成基本项目,或者按照“入门”指南之一,就像开始构建RESTful Web服务一样。 除了更容易理解消化,这些指南是非常专注于任务,其中大部分都是基于Spring Boot。 它们还涵盖了Spring解决特定问题时可能需要考虑的Spring组合中的其他项目。
2. Spring框架简介
Spring Framework是一个Java平台框架,它为开发Java应用程序的全面的基础架构支持。Spring处理基础架构,以便你可以专注于应用程序。
Spring使你能够从“普通旧Java对象”(POJO)构建应用程序,并将企业服务非侵入性地应用于POJO。 此功能适用于Java SE编程模型和完整和部分Java EE。
作为应用程序开发人员,你可以如何从Spring平台中受益的示例:
- 在数据库事务中执行Java方法,而不必处理事务API。
- 使本地Java方法成为远程过程,而不必处理远程API。(意思就是无须管相关的远程调用api,Spring已经封装好了,你自己只需要专注自己的逻辑即可,下同,不再解释)
- 使本地Java方法成为管理操作,而不必处理JMX API。
- 使本地Java方法成为消息处理程序,而不必处理JMS API。
2.1 依赖注入和控制反转
Java应用程序 - 一个宽松的术语,其运行范围从受限的嵌入式应用程序到n层,服务器端企业应用程序 - 通常由协作形成应用程序的对象组成。 因此,在一个应用程序中的对象具有关于彼此的依赖性。
尽管Java平台提供了丰富的应用程序开发功能,但它缺乏将基本构建块组织成一个整体的手段,将该任务留给架构师和开发人员。虽然可以使用设计模式,例如工厂,抽象工厂,建筑模式,装饰器和服务定位器等设计模式来组成构成应用程序的各种类和对象实例,这些模式是:最佳实践给出一个名字,有什么模式的描述,如何应用它,它解决的问题,等等。 模式是形式化的最佳实践,你必须在应用程序中实现自己。
Spring框架控制反转(IoC)组件通过提供一种形式化的手段将不同的组件组成一个完全可用的应用程序来解决这个问题。 Spring框架将形式化的设计模式编译为可以集成到自己的应用程序中的第一类对象。 许多组织和机构以这种方式使用Spring框架来设计强大的,可维护的应用程序。(就是将各种设计模式融合到框架中,而开发人员只需要关注自己的逻辑,在不知不觉中就已经用到了最佳的设计模式,自己的代码也得以健壮)
背景
“现在的问题是,什么方面的控制是(他们)反转?” Martin Fowler在2004年在他的网站上提出了关于反转控制(IoC)的问题.Fowler建议重命名这个原则,使其更一目了然,并提出依赖注入。
2.2 Modules
Spring框架由大约20个功能模块组成。 这些模块分为核心容器,数据访问/集成,Web,AOP(面向方面的编程),仪器,消息传递和测试,如下图所示。
图2.1 Spring框架的概述
以下部分列出了每个功能的可用模块及其构件名称及其涵盖的主题。 构件名称与构件关联id用于管理工具的依赖。
2.2.1 Core Container
核心容器由spring-core,spring-beans,spring-context,spring-context-support和spring-expression(Spring Expression Language)模块组成。
spring-core和spring-beans模块提供了框架的基本部分,包括IoC和依赖注入功能。 BeanFactory是一个复杂的工厂模式的实现。 它消除了编程单例的需要(程序员不必对单例亲力亲为),并允许你从实际的程序逻辑中分离依赖性的配置和规范。
Context(spring-context)模块建立在Core和Beans模块提供的实体基础之上:它是一种以类似于JNDI注册表的框架样式方式访问对象的手段。 Context模块从Beans模块继承其特性,并增加了对国际化(例如使用资源束),事件传播,资源加载以及通过例如Servlet容器的透明创建上下文的支持。 Context模块还支持Java EE功能,如EJB,JMX和基本远程处理。ApplicationContext接口是Context模块的焦点。spring-context-support提供支持将常见的第三方库集成到Spring应用程序上下文中,特别是用于缓存(EhCache,JCache)和定时任务等(CommonJ,Quartz)。
spring-expression模块提供了一个强大的表达式语言,用于在运行时查询和操作对象图。 它是JSP 2.1规范中规定的统一表达式语言(统一EL)的扩展。 该语言支持设置和获取属性值,属性赋值,方法调用,访问数组的内容,集合和索引器,逻辑和算术运算符,命名变量,以及通过Spring IoC容器中的名称检索对象。 它还支持列表投影和选择以及公共列表聚合。
2.2.2 AOP and Instrumentation
spring-aop模块提供了一个符合AOP Alliance-compliant的面向方面的编程实现,允许你定义例如方法拦截器和切入点来干净地解耦实现应该分离的功能的代码。 使用源代码级元数据功能,你还可以以类似于.NET属性的方式将行为信息合并到代码中。
单独的spring-aspects模块提供与AspectJ的集成。
spring-instrument-tomcat 模块提供类仪器支持和类加载器实现以在某些应用服务器中使用。 spring-instrument-tomcat模块包含Spring的Tomcat的工具代理。
2.2.3 Messaging
Spring Framework 4包括一个 Spring消息传递模块,它具有来自 Spring Integration项目的关键抽象,例如 Message, MessageChannel, MessageHandler和其他, 用作基于消息传递的应用程序的基础。 该模块还包括一组用于将消息映射到方法的注解,类似于基于 Spring MVC注解的编程模型。
2.2.4 Data Access/Integration
数据访问/集成层由JDBC,ORM,OXM,JMS和Transaction模块组成。
spring-jdbc模块提供了一个JDBC抽象层,消除了对繁琐的JDBC编码和解析数据库供应商特定的错误代码的需要。
spring-tx模块支持实现特殊接口的类以及所有POJO(普通Java对象)的编程和声明事务管理。
spring-orm模块为流行的对象关系映射API提供集成层,包括JPA和Hibernate。使用spring-orm模块,您可以使用这些O / R映射框架结合Spring提供的所有其他功能,例如前面提到的简单声明式事务管理功能。
spring-oxm模块提供了一个支持对象/ XML映射实现的抽象层,例如JAXB,Castor,JiBX和XStream。
spring-jms模块(Java消息服务)包含用于生成和使用消息的功能。从Spring Framework 4.1开始,它提供了与spring-messaging模块的集成。
2.2.5 Web
Web层由spring-web,spring-webmvc和spring-websocket模块组成。(注:这里和4的文档比少了spring-webmvc-portlet模块)
spring-web模块提供基本的面向Web的集成功能,例如多部分文件上传功能和使用Servlet侦听器和面向Web的应用程序上下文来初始化IoC容器。 它还包含一个HTTP客户端和Web的相关部分的Spring的远程支持。
spring-webmvc模块(也称为Web-Servlet模块)包含用于Web应用程序的Spring的模型视图控制器(MVC)和REST Web服务实现。 Spring的MVC框架提供了domain model(领域模型)代码和Web表单之间的清晰分离,并且集成了Spring Framework 所有的其他功能。
2.2.6 Test
spring-test模块支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。 它提供了SpringApplicationContexts的一致加载和这些上下文的缓存。 它还提供了 mock objects(模拟对象),您可以使用它来单独测试您的代码。
2.3 使用场景
之前描述的构建块使Spring成为许多场景中的逻辑(也就是下意识合理的)选择,从资源受限的嵌入式程序到成熟的企业应用程序都可以使用 Spring事务管理功能和 web框架集成。
图2.2。 典型的完整Spring Web应用程序
Spring的声明式事务管理特性使Web应用程序具有完全事务性,就像使用EJB容器管理的事务一样。 所有的定制业务逻辑都可以通过简单的POJO实现,并由Spring的IoC容器管理。 其他服务包括独立于Web层的发送电子邮件和验证的支持,允许你选择执行验证规则的位置。 Spring的ORM支持集成了JPA和Hibernate;(注:和4的文档比少了JDO) 例如,当使用Hibernate时,可以继续使用现有的映射文件和标准的Hibernate SessionFactory配置。 表单控制器将Web层与域模型无缝集成,从而无需使用ActionForms或其他将HTTP参数转换为域模型值的类。(注:也就是这些参数无须单独创建POJO来表达)
图2.3。 Spring中间层使用第三方Web框架
有时情况不允许你完全切换到一个不同的框架。 Spring框架不强迫你使用它里面的一切; 它不是一个全有或全无的解决方案。 使用Struts,Tapestry,JSF或其他UI框架构建的现有前端可以与基于Spring的中间层集成,它允许你使用Spring事务功能。 你只需要使用ApplicationContext连接你的业务逻辑,并使用WebApplicationContext来集成你的web层。
图2.4。 远程使用场景
当您需要通过Web服务访问现有代码时,可以使用Spring的Hessian-,Rmi-或HttpInvokerProxyFactoryBean类(注:此处和4的文档对比,4使用的是JaxRpcProxyFactory 类
)。 启用对现有应用程序的远程访问并不困难。
图2.5 EJB - 包装现有POJO
Spring Framework还为Enterprise JavaBeans提供了一个 访问和抽象层,使您可以重用现有的POJOs,并将其封装在无状态会话bean中,以用于可能需要声明性安全性的扩展即有安全故障的Web应用程序中。
2.3.1 依赖关系管理和命名约定
依赖管理和依赖注入是不同的。为了让 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.M4.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 | 基于代理的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 | 核心应用程序,由许多其他Spring模块使用 |
org.springframework | spring-expression | Spring Expression Language (SpEL) |
org.springframework | spring-instrument | JVM引导的工具代理 |
org.springframework | spring-instrument-tomcat | Tomcat的工具代理 |
org.springframework | spring-jdbc | JDBC支持包,包括DataSource设置和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 | 支持单元测试和集成测试的Spring组件 |
org.springframework | spring-tx | T事务基础设施,包括DAO支持和集成制定 |
org.springframework | spring-web | Web支持包,包括客户端和Web远程处理 |
org.springframework | spring-webmvc | Web应用程序的REST Web服务和模型 - 视图 - 控制器实现 |
org.springframework | spring-websocket | WebSocket和SockJS实现,包括STOMP支持 |
Spring依赖管理
虽然Spring提供了大量对企业和其他外部工具的集成和支持,它有意地将其强制依赖保持在绝对最低限度:你无需查找和下载(甚至自动)大量的jar库,以便 使用Spring的简单用例。 对于基本依赖注入,只有一个强制性的外部依赖,这是用于日志记录的(有关日志选项的更详细描述,请参见下文)。
接下来,我们概述配置依赖于Spring的应用程序所需的基本步骤,首先使用Maven,然后使用Gradle,最后使用Ivy。 在所有情况下,如果有什么不清楚,请参考依赖管理系统的文档,或者查看一些示例代码 - Spring本身使用Gradle在构建时管理依赖关系,我们的示例主要使用Gradle或Maven。
Maven 依赖管理
如果你使用Maven进行依赖关系管理,你甚至不需要显式提供日志记录依赖关系。 例如,要创建应用程序上下文并使用依赖注入来配置应用程序,你的Maven依赖关系将如下所示:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.M4</version>
<scope>runtime</scope>
</dependency>
</dependencies>
就是这样。 注意,如果不需要针对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>
以及快照:
<repositories>
<repository>
<id>io.spring.repo.maven.snapshot</id>
<url>http://repo.spring.io/snapshot/</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Maven “Bill Of Materials” Dependency
在使用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.M4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
使用 BOM后,当依赖 Spring Framework组件后,无需再指定 属性
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
通过Gradle 做依赖管理
要将Spring存储库与Gradle构建系统一起使用,请在repositories部分中包含相应的URL:
repositories {
mavenCentral()
// and optionally...
maven { url "http://repo.spring.io/release" }
}
你可以根据需要将 repositories 中URL从/ release更改为/ milestone或/ snapshot。 一旦配置了 repositories,就可以按照通常的Gradle方式声明依赖关系:
dependencies {
compile("org.springframework:spring-context:5.0.0.M4")
testCompile("org.springframework:spring-test:5.0.0.M4")
}
Ivy 依赖管理
如果你喜欢使用Ivy来管理依赖,那么有类似的配置选项。
要配置Ivy指向Spring存储库,请将以下解析器添加到你的ivysettings.xml:
<resolvers>
<ibiblio name="io.spring.repo.maven.release"
m2compatible="true"
root="http://repo.spring.io/release/"/>
</resolvers>
你可以根据需要将root URL从/ release /更改为/ milestone /或/ snapshot /。
配置后,你可以按照通常的方式添加依赖关系。 例如(在ivy.xml中):
<dependency org="org.springframework"
name="spring-core" rev="5.0.0.M4" conf="compile->runtime"/>
Zip文件分发
尽管使用支持依赖性管理的构建系统是获取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。 还分发了里程碑和快照的分发。
2.3.2 日志
日志记录是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
不幸的是,公共日志中的运行时发现算法虽然对于终端用户方便,但是是有问题的。 如果我们可以时光倒流并启动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.M4</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
现在这个应用程序运行不了,因为没有在类路径上实现JCL API,所以要解决它需要提供一个新的。 在下一节中,我们将向你展示如何使用SLF4J提供JCL的替代实现。
使用 SLF4J
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.M4</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>
这可能看起来像很多依赖只是为了获得一些日志。 它的确如此,但它是可选的,它在关于类加载器的问题上应该比 commons-logging 表现的更加的好,特别是当它运行在在一个严格的容器中像OSGi平台。 据称,还有一个性能优势,因为绑定是在编译时,而不是运行时。
SLF4J用户中更常见的选择是使用较少的步骤和生成较少的依赖关系,它是直接绑定到Logback。 这消除了额外的绑定步骤,因为Logback直接实现SLF4J,所以你只需要依赖于两个不是四个库(jcl-over-slf4j和logback)。 如果你这样做,你可能还需要从其他外部依赖(不是Spring)中排除slf4j-api依赖,因为你只需要在类路径上有一个版本的API。
使用Log4J
许多人使用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.M4</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</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
Runtime Containers with Native JCL
许多人在一个容器中运行他们的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依赖关系,而不是容器。该选项并不总是开放的,但在公共领域有许多其他建议替代方法,你的里程可能会根据容器的确切版本和功能集而有所不同。