通过maven创建父子项目
# 通过maven创建父子项目
Maven 是一个非常流行的 Java 项目构建工具和项目管理工具。今天要分享的是它其中的父子项目和聚合项目。
Maven 中的父子项目
和聚合项目
都是为了更好地管理和构建大型项目而设计的。
maven的工程类型:
- war-工程,Web应用程序归档(WAR)是专门用来部署Web应用程序到Servlet容器(如Tomcat)中的格式。
- jar-工程,用于打包Java类文件、相关的元数据以及资源(如属性文件)到一个JAR文件中。它通常用于库项目,这些库可以被其他项目依赖。
- pom-工程,就是聚合工程,这种类型的工程本身不包含源代码,通常用于多模块项目的顶层,协调多个子模块的构建过程。
- ....
# 背景
在大型或复杂的项目中,通常包含多个子模块,每个子模块负责不同的功能或组件。如果要构建整个项目——手动构建每个子模块会非常耗时且容易遗漏,且容易出错(可能会遇到构建配置不一致、构建顺序等问题)。
同时,不同的子模块可能依赖于相同的第三方库的不同版本,这可能导致版本冲突。于是,维护好每个子模块的依赖版本也成为了一项挑战。比如:如果每个模块都引入相同的xxx.jar,在需要修改时,每一个都需要修改。
不同业务的子模块中可能需要相同的配置,如何避免重复编写也是一个核心问题。
.....
为了解决上述这些问题,开发者设计了2种解决方案,分别为:父子项目、聚合项目。它们各自的特点如下:
# 父子项目
- 简化配置:
- 父子项目模式允许子项目继承父项目的配置,从而减少每个子项目的 POM 文件中的冗余配置。
- 这使得配置更加一致,也减少了出错的机会。
- 统一版本控制:
- 通过
<dependencyManagement>
标签,父项目可以统一管理依赖版本,确保所有子项目使用相同的版本。 - 这有助于避免版本冲突,并确保依赖的一致性。
- 通过
- 易于维护:
- 当需要更改全局配置(如编译插件版本)时,只需在父项目中进行更改,所有子项目都会自动采用这些更改。
- 这大大简化了维护工作,并减少了出错的可能性。
- 覆盖配置:
- 子项目可以覆盖或添加特定的配置,以适应不同的需求。
- 这种机制提供了足够的灵活性,使得子项目可以根据自身需求进行定制。
# 聚合项目
- 模块化管理:
- 聚合项目可以帮助组织和管理多个子模块,使得大型项目可以被分解成较小的部分,易于理解和维护。
- 这种结构有助于清晰地区分不同的功能区域,并简化了构建过程。
- 单一构建命令:
- 使用一个命令即可构建所有子模块,简化了构建过程。
- 这有助于确保所有子模块都被正确构建,并且减少了构建错误的机会。
- 递归构建:
- 当您执行聚合项目的构建命令时,Maven 会递归地构建所有的子模块,确保所有模块都被正确构建。
- 这有助于确保所有子模块都处于最新的状态,并且依赖关系得到正确处理。
# 总结
父子项目 主要解决了配置复用和版本控制的问题,使得多个子项目可以继承父项目的通用配置,减少了重复配置的工作量。而聚合项目 则解决了大型项目中的模块化管理和构建效率问题,使得大型项目可以被分解成多个易于管理的子模块,并通过单一命令进行构建。
实际开发中,它们两种往往是结合一起来使用。
# 父子项目简介
什么被叫做父子项目,其实我们创建一个基本的SpringBoot项目,就是一个父子项目。pom文件中有这么一个标签,parent
<parent>
<groupId>org.springframework</groupId>
<artifactId>my-parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
2
3
4
5
只要我们有引用父项目,那么它就是一个父子项目。引用后的项目,通常会继承父项目的依赖包括版本信息,但需要注意的是maven中的继承跟Java一样是——单继承。也就是说一个pom文件中,只能有一个parent标签。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.21</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.21</version>
</dependency>
</dependencies>
</dependencyManagement>
2
3
4
5
6
7
8
9
10
11
12
13
14
- dependencyManagement
在父子项目中,常常会看到该标签,它dependencyManagement
跟dependencies
很像,它们的作用基本相同,都是用于管理项目的依赖,但区别也有,其中最大一个区别就是:
- dependencyManagement:该标签是声明项目所需的依赖项,但不会实际引入这些依赖项。通常位于父项目的pom文件中
- dependencies:声明项目所需的依赖项和版本号,会引入对应的jars
在父项目中使用dependencyManagement
后,声明的引用,同样会被子项目继承,不过并不会真正引入对应的jars,只有在代码中使用了对应的代码,才会引入。
此外,如果子项目中,在 <dependencies>
中显式指定了依赖的版本,那么 <dependencyManagement>
中的版本将被忽略,使用显示指定了的依赖版本。
# 聚合项目简介
在 Maven 中,<modules>
标签用于定义聚合项目中的子模块列表。聚合项目(有时也称为多模块项目或多项目)是指一个 POM 文件,它可以包含多个子模块,每个子模块都是一个独立的 Maven 项目。聚合项目的主要目的是为了方便管理和构建多个相关的子项目。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.example</groupId>
<artifactId>my-aggregated-project</artifactId>
<version>1.0.0</version>
<!-- 其他配置... -->
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
</modules>
<!-- 其他配置... -->
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在上述配置中,共有3个子模块,分别为common
、service
、web
。每个子module中使用parent标签,它们的坐标就是父pom中声明的坐标。
在构建时,Maven 会首先构建聚合项目本身,然后构建所有列出的子模块,而子模块的顺序,则是按照 <modules>
标签中列出的顺序依次构建。
注意:
聚合关系,也就是使用module标签,它是不会传递依赖给子模块或从子模块接收依赖的。
# 扩展
<packaging>
(可选)
- 定义项目的打包类型,比如
pom
表示这是一个聚合项目。 - 默认情况下,如果未指定
<packaging>
元素,则使用jar
。
Maven 支持多种打包类型,以下是几种常见的选项:
- jar:Java Archive,是最常用的打包方式之一,适用于大多数Java项目,特别是库项目。
- war:Web application ARchive,专门用于Web应用程序的打包,包含JSP、servlet、Java类文件以及web应用所需的资源。
- ear:Enterprise ARchive,用于企业级应用的打包,可以包含多个EJB模块、WAR模块和其他库。
- pom:Project Object Model,当项目主要目的是作为父项目或聚合项目来管理其他子模块时使用。
- maven-plugin:用于打包Maven插件。
- aar:Android ARchive,虽然不是Maven内置支持的格式,但可以通过配置来支持Android库项目的打包需求。
- bundle:OSGi bundle,适用于需要遵循OSGi规范的项目。
为什么springboot项目,且项目是web工程,但打包后却是jar文件?
- Spring Boot 项目通常被打包为 JAR 文件,即使它们实际上是 Web 应用程序。这背后有几个关键原因和机制:
- 内嵌服务器:Spring Boot 的核心特性之一是它能够内嵌一个Web服务器(如Tomcat、Jetty或Undertow)。这意味着你不需要单独部署WAR文件到外部的Servlet容器中。相反,你可以直接运行JAR文件,它会启动内嵌的服务器并开始监听请求。这种做法简化了部署流程,因为你只需要一个JAR文件即可。
- 自包含的应用程序:Spring Boot旨在创建自包含的、独立运行的应用程序。通过将所有依赖(包括Web服务器)打包进一个JAR文件中,开发者可以轻松地在任何有Java环境的地方运行这个应用,无需担心配置额外的服务器或处理复杂的部署步骤。
- 简化部署和运维:使用JAR格式使得部署更加简单,因为它减少了需要管理的不同文件的数量,并且可以通过简单的命令(例如
java -jar your-application.jar
)来启动应用。 - Spring Boot Maven/Gradle插件支持:Spring Boot提供了专门的Maven和Gradle插件,这些插件帮助自动化构建过程,并确保生成的JAR文件不仅包含了应用程序代码,还包括了所有必要的依赖以及启动脚本。这些插件使得即使是Web应用程序也可以被正确地打包成一个可执行的JAR文件。