前面介绍了spring各个基础模块的作用,这些模块使Spring成为许多场景中的优先选择,从在资源受限设备上运行的嵌入式应用程序到使用Spring的事务管理功能和Web框架集成的成熟企业应用程序等等。
典型的完整的spring web应用程序如下:
Spring的声明式事务管理功能使Web应用程序完全是事务性的,就像使用EJB容器管理的事务一样。您可以使用简单的POJO实现所有自定义业务逻辑,并由Spring的IoC容器管理。其他服务包括支持发送独立于Web层的电子邮件和验证,这使您可以自定义执行验证规则的位置。Spring的ORM支持与JPA,Hibernate和JDO集成在一起; 例如,在使用Hibernate时,您可以继续使用现有的映射文件和标准的Hibernate SessionFactory配置。表单控制器将Web层与域模型无缝集成,无需使用ActionForms 或其他将HTTP参数转换为域模型值的类。
Spring中间层使用第三方Web框架:
有时情况不允许开发人员完全切换到不同的框架。Spring框架并没有强迫你在使用它时不能使用别的框架; 它不是一个 全有或全无的解决方案。使用Struts,Tapestry,JSF或其他UI框架构建的现有前端可以与基于Spring的中间层集成,从而允许您使用Spring事务功能。您只需将ApplicationContext使用WebApplicationContext对象连接业务逻辑并使用它来集成Web层。
远程处理使用场景:
当你需要通过Web服务来访问现有的功能,你可以使用Spring的 Hessian-,Burlap-,Rmi-或JaxRpcProxyFactory类。启用对现有应用程序的远程访问并不困难。
EJB - 包装现有的POJO:
Spring Framework还为Enterprise JavaBeans 提供了一个访问和抽象层,使您能够重用现有的POJO并将它们包装在无状态会话Bean中,以便在可能需要声明性安全性的可伸缩,故障安全Web应用程序中使用。
依赖管理和命名约定
依赖管理和依赖注入是不同的事情。要将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.24.RELEASE.jar)。
Spring Framework的每个版本都会将工件发布到以下位置:
Maven Central,它是Maven查询的默认存储库,不需要任何特殊配置即可使用。Spring所依赖的许多公共库也可以从Maven Central获得,而Spring社区的很大一部分使用Maven进行依赖管理,因此这对他们来说很方便。这里的罐子的名称是形式spring-*-
.jar,Maven groupId是org.springframework。
在专门为Spring托管的公共Maven存储库中。除了最终的GA版本之外,该存储库还托管了开发快照和里程碑。jar文件名与Maven Central的格式相同,因此这是一个有用的地方,可以让Spring的开发版本与Maven Central中部署的其他库一起使用。此存储库还包含一个捆绑包分发zip文件,其中包含捆绑在一起的所有Spring jar,以便于下载。
因此,您需要决定的第一件事是如何管理您的依赖项:我们通常建议使用Maven,Gradle或Ivy等自动化系统,但您也可以通过自己下载所有jar来手动完成。
您可用参考下面的Spring工件列表。
Spring依赖和依赖于Spring
尽管Spring为大量企业和其他外部工具提供集成和支持,但它有意将其强制依赖性保持在最低限度:您不必定位和下载(甚至自动)大量jar库以便将Spring用于简单的用例。对于基本依赖项注入,只有一个强制性外部依赖项,即用于日志记录(有关日志记录选项的详细说明,后面讨论)。
下面是配置依赖于Spring的应用程序所需的基本步骤,首先是Maven,然后是Gradle,最后是使用Ivy。
Maven依赖管理
如果您使用Maven进行依赖项管理,则不需要显式提供日志记录依赖项。例如,要创建应用程序上下文并使用依赖项注入来配置应用程序,您的Maven依赖项将如下所示:
请注意,如果您不需要针对Spring API进行编译,则可以将范围声明为运行时,这通常是基本依赖项注入用例的情况。上面的示例适用于Maven Central存储库。要使用Spring Maven存储库(例如,用于里程碑或开发人员快照),您需要在Maven配置中指定存储库位置,release版本:
里程碑版本:
快照版本:
使用Maven时,可能会意外混合不同版本的Spring JAR。例如,您可能会发现第三方库或另一个Spring项目将旧版本的传递依赖性拉入其中。如果您自己明确声明直接依赖,则可能会出现各种意外问题。
为了克服这些问题,Maven支持“物料清单”(BOM)依赖性的概念。您可以spring-framework-bom在您的dependencyManagement 部分中导入以确保所有Spring依赖项(直接和传递)都在同一版本。
使用BOM的另一个好处是,
Gradle依赖管理
要将Spring存储库与Gradle构建系统一起使用,请在以下repositories部分中包含相应的URL :
您可以更改repositories的URL, /release到/milestone或/snapshot。配置存储库后,您可以使用通常的Gradle方式声明依赖项:
lvy依赖管理
如果您更喜欢使用Ivy来管理依赖项,那么有类似的配置选项。要将Ivy配置为指向Spring存储库,请将以下解析程序添加到 ivysettings.xml:
您可以更改root的URL, /release/到/milestone/或/snapshot/。配置完成后,您可以按常规方式添加依赖项。例如(in ivy.xml):
下载zip压缩文件
尽管使用支持依赖关系管理的构建工具是获取Spring Framework的推荐方法,但仍可以下载zip文件。
压缩文件链接发布到Spring Maven Repository(这只是为了方便起见,您不需要Maven或任何其他构建系统来下载它们)。
要下载zip文件,请打开Web浏览器以访问 https://repo.spring.io/release/org/springframework/spring,然后为所需的版本选择相应的子文件夹。例如spring-framework- {spring-version} -RELEASE-dist.zip。还会针对里程碑和 快照发布版本。
日志记录
日志记录是Spring的一个非常重要的依赖项,因为
a) 它是唯一强制性的外部依赖项,
b)每个人都喜欢从他们使用的工具中看到一些输出,
c) Spring集成了许多其他工具,所有这些工具也都是选择日志记录依赖项。
应用程序开发人员的目标之一通常是在整个应用程序的中心位置配置统一日志记录,包括所有外部组件。由于有很多日志框架选择,因此这比以往更难。
Spring中的强制日志记录依赖是Jakarta Commons Logging API(JCL)。我们针对JCL进行编译,并且我们还使Log扩展Spring Framework的类可以看到JCL 对象。对于用户来说,所有版本的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用户,这是您的依赖声明:
这是一个用于登录控制台的log4j.properties示例:
要使用Log4j 2.X与JCL,所有你需要做的就是把Log4j的在类路径,并为其提供一个配置文件(log4j2.xml,log4j2.properties或其他 支持的配置格式)。对于Maven用户,所需的最小依赖项是:
如果您还希望启用SLF4J,例如对于默认情况下使用SLF4J的其他库,还需要以下依赖项:
以下是log4j2.xml打印到控制台的示例:
不要使用Commons Logging
不幸的是,标准commons-loggingAPI中的运行时发现算法虽然对最终用户来说很方便,但可能会有问题。如果您想避免使用JCL的标准查找,基本上有两种方法可以将其关闭:
排除spring-core模块的依赖关系(因为它是唯一明确依赖的模块commons-logging)
依赖于一个特殊的commons-logging依赖项,用一个空jar替换库
要排除公共日志记录,请将以下内容添加到您的dependencyManagement部分:
现在这个应用程序已经崩溃,因为类路径上没有JCL API的实现,所以为了修复它,必须提供一个新的。例如SLF4J。
将SLF4J与Log4j或Logback一起使用
Simple Logging Facade for Java(SLF4J)是一种常用的日志API,供其他常用于Spring的库使用。它通常与Logback一起使用, 后者是SLF4J API的本机实现。
SLF4J提供了对许多常见日志框架(包括Log4j)的绑定,它也反过来了:其他日志框架与其自身之间的桥梁。因此,要在Spring中使用SLF4J,您需要commons-logging使用SLF4J-JCL桥替换依赖项。完成后,从Spring中记录调用将转换为对SLF4J API的日志记录调用,因此,如果应用程序中的其他库使用该API,那么您只需一个位置即可配置和管理日志记录。
一个常见的选择可能是将Spring桥接到SLF4J,然后提供从SLF4J到Log4j的显式绑定。您需要提供多个依赖项(并排除现有的 commons-logging):JCL桥,与Log4j绑定的SLF4j以及Log4j提供程序本身。在Maven,可以这样配置:
SLF4J用户使用较少步骤并生成较少依赖关系的更常见选择是直接绑定到Logback。这消除了额外的绑定步骤,因为Logback直接实现了SLF4J,所以你只需要依赖两个库,即jcl-over-slf4j和logback):
使用JUL(java.util.logging)
如果在类路径中未检测到Log4j,则Commons Logging将默认委派给java.util.logging。因此,没有特殊的依赖关系来设置:只需在没有外部依赖关系的情况下将日志输出用于java.util.logging(在JDK级别使用自定义或默认JUL设置)或使用应用程序服务器的日志系统(及其系统范围的JUL设置)。
运行于WebSphere
Spring应用程序可以在一个容器上运行,该容器本身提供JCL的实现,例如IBM的WebSphere Application Server(WAS)。这不会导致问题本身,但会导致需要理解的两种不同情况:
在“parent first” ClassLoader委托模型(WAS上的默认模式)中,应用程序将始终获取服务器提供的Commons Logging版本,委托给WAS日志记录子系统(实际上是基于JUL)。JCL的应用程序提供的变体,无论是标准的Commons Logging还是JCL-over-SLF4J桥,都将被有效地忽略,以及任何本地包含的日志提供程序。
使用“parent last”委托模型(常规Servlet容器中的默认值,但WAS上的显式配置选项),将选择应用程序提供的Commons Logging变体,使您能够设置本地包含的日志提供程序,例如Log4j或者在您的应用程序中进行Logback。如果没有本地日志提供程序,则默认情况下,常规Commons Logging将委派给JUL,有效地记录到WebSphere的日志记录子系统,就像在“父第一”方案中一样。
总而言之,我们建议在“parent last”模型中部署Spring应用程序,因为它自然允许本地提供程序以及服务器的日志子系统。