2.3.1 依赖管理和命名约定
依赖管理和依赖注入是截然不同的概念。为了在自己的应用程序中使用Spring的框架所拥有的强大功能(如依赖注入),需要导入所需的全部jar包,并在运行时放在classpath下,有时需要在编译期放在classpath下。这些依赖并不是被注入的虚拟组件,而是文件系统上真实的物理资源。依赖管理涉及到定位这些资源、存储并把它们添加到classpath下。依赖可能是直接的(比如我的应用程序在运行时依赖于Spring),也可能是间接的(比如我的应用程序依赖于commons-dbcp,而commons-dbcp又依赖于commons-pool)。间接的依赖又被称作“传递依赖”,传递依赖是最难识别和管理的。
如果你准备使用Spring框架,那么你需要拷贝一份所需模块的Spring的jar包到你的应用程序中。为了便于使用,Spring被打包成一系列独立的模块以尽可能地减少依赖,比如,如果不是在写一个web应用,那就没必要引入spring-web模块。这篇文档中涉及到的Spring模块,我们使用都是各个模块的简称。Spring框架的每个模块都遵循spring-*或spring-*.jar的命名约定,其中,*代表模块的简称(比如,spring-core、spring-webmvc、spring-jms等等)。实际使用的jar包正常情况下都是带有版本号的(比如,spring-core-4.3.8.RELEASE.jar)。
每个版本的Spring都会在以下地方发布artifact:
- Maven中央仓库,这是Maven默认的查询仓库,并且不需要特殊的配置就可以使用。许多Spring依赖的公共库也可以从Maven中央仓库获得,并且大部分的Spring社区也使用Maven作为依赖管理工具,所以很方便。Maven中的jar包命名格式为spring-*<version>.jar,其groupId是org.springframework。
- 专门托管Spring的公共的Maven仓库。除了最终的GA版本,这个仓库也托管了开发的快照版本和里程碑版本。jar包和Maven中央仓库中的命名一致,所以这也是一个获取Spring的开发版本的地方,可以和Maven中央仓库中部署的其它库一起使用。这个仓库也包含了所有Spring jar包的发行版的zip文件,以便于下载。
因此,使用Spring框架之前前首先要做的事就是决定如何管理依赖关系,我们一般推荐使用自动化的构建工具,比如Maven、Gradle或Ivy,当然你也可以手动下载所有的jar包。
下面列出了Spring的artifact,每个模块更完整的描述,参考2.2 模块章节。
表2.1. Spring框架的artifact
| groupId | artifactId | 描述 |
|---|---|---|
| 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把强制性的外部依赖降到了最低,这样开发者就不需要为了简单地使用Spring而去寻找和下载大量的依赖jar包了。Spring基本的依赖注入模块只有一个强制性的外部依赖,那就是日志管理(参考下面关于日志管理选项的详细描述)。
下面介绍基于Spring的应用的基本配置步骤,首先介绍使用Maven构建,然后介绍Gradle构建,最后介绍Ivy。在所有案例中,如果有什么不清楚的地方,参考所用的构建工具的文档或查看一些范例代码——Spring源码构建时使用Gradle管理依赖,所以我们的范例大部分使用Gradle或Maven。
Maven依赖关系管理
如果使用Maven作为依赖管理工具,甚至不需要明确地提供日志管理的依赖。例如,创建应用上下文并使用依赖注入(DI)配置应用程序,Maven的依赖关系如下所示:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.8.RELEASE</version>
<scope>runtime</scope>
</dependency>
</dependencies>
这就是使用Spring依赖注入(DI)的典型案例。注意,如果您不需要针对Spring API进行编译,可以把scope声明为runtime。
上面的示例使用Maven中央仓库,如果想使用Spring的Maven仓库(例如,获取里程碑版本或开发快照版本),需要在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 BOM依赖
当使用Maven构建工具管理依赖时可能会不小心混合了Spring不同版本的jar包。例如,你可能会发现第三方库或其它的Spring项目存在旧版本的传递依赖。如果没有明确地声明直接依赖,将会导致各种各样不可预知的问题。
为了解决这个问题,Maven提出了“物料清单式”(BOM)依赖的概念。可以在dependencyManagement部分导入spring-framework-bom以保证所有的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的另外一个好处是不再需要指定<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管理依赖关系有相似的配置选项。
例如要配置Ivy指向Spring仓库,请将以下解析器添加到您的ivysettings.xml中:
<resolvers>
<ibiblio name="io.spring.repo.maven.release"
m2compatible="true"
root="http://repo.spring.io/release/"/>
</resolvers>
可以根据需要把repositories URL中的/release修改为/milestone或/snapshot。
配置完成后,您可以按常规的方式添加依赖项。 例如(在ivy.xml中):
<dependency org="org.springframework"
name="spring-core" rev="4.3.8.RELEASE" conf="compile->runtime"/>
发行版的Zip文件
虽然使用构建工具系统管理依赖是获取Spring框架的推荐方法,但是也可以通过下载Spring的发行版zip文件的方式来使用Spring框架。
发行版zip文件发布在了Sprng的Maven仓库上(这只是为了方便,不需要额外的Maven或其它构建系统去下载它们)。
浏览器中打开http://repo.spring.io/release/org/springframework/spring,并选择合适版本的子目录,就可以下载发行版的zip文件了。发行文件以-dist.zip结尾,例如,spring-framework-{spring-version}-RELEASE-dist.zip。发行文件也包含里程碑版本和快照版本。