生命周期与模块化
一、生命周期
一个完整的项目构建过程包括:清理、编译、测试、打包、集成测试、验证、部署。 maven生命周期主要有以下三个部分组成:
- clean:清理项目
- pre-clean:执行清理前的工作
clean
:清理上一次构建生成的所有文件- post-clean:执行清理后的文件
- default:构建项目(生命周期中最核心的)
- validate
- generate-sources
- process-sources
- generate-resources
- process-resources:复制并处理资源文件,至目标目录,准备打包。
compile
:编译项目的源代码。- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources:复制并处理资源文件,至目标测试目录。
test-compile
:编译测试源代码。- process-test-classes
test
:使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。- prepare-package
- package:接受编译好的代码,打包成可发布的格式,如 JAR 。
- pre-integration-test
- integration-test
- post-integration-test
- verify
install
:将包安装至本地仓库,以让其它项目依赖。deploy
:将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
- site:生成项目站点(根据pom中的信息自动生成)
- pre-site :在生成项目站点前要完成的工作
site
:生成项目的站点文档- post-site:在生成项目站点后要完成的工作
- site-deploy:发布生成的站点到服务器上
说明
- 以上三个生命周期彼此是独立的
- 如果执行任何一个具体的操作,则会从当前周期的第一个操作开始执行,直到当前指定的操作。
# -D 表示后面要附加命令的参数
# -Dmaven.test.skip=true 表示在执行命令的过程中跳过测试
$ mvn clean package -Dmaven.test.skip=true
二、插件
1、概述
**插件是maven的核心,所有执行的操作都是基于插件来完成的。**为了让一个插件中可以实现众多的类似功能,maven为插件设定了目标,一个插件中有可能有多个目标。其实生命周期中的重要的每个阶段都是由插件的一个具体目标来执行的。
1)插件
Maven 的核心程序仅仅负责宏观调度,不做具体工作。具体工作都是由 Maven 插件完成的。例如:编译就是由 maven-compiler-plugin-3.1.jar 插件来执行的。
2)目标
编译器插件有两个目标。两者都已经绑定到 Maven 生命周期中的适当阶段,因此会在各自的阶段自动执行。
- compiler:compile绑定到compile阶段,用于编译 main 目录下的源文件。
- compiler:testCompile绑定到测试编译阶段,用于编译 test 目录下的源文件。
$ mvn compiler:compile
# 其中,mvn为Maven核心程序
# compiler为其中的某个插件,用于编译项目
# compile为compiler的目标,指定具体的操作,用于编译 main 定义的源文件
# 默认
$ mvn compile
$ mvn 插件名称:目标
# 编译 main 目录下的代码
$ mvn compile:compile
# 编译 test 目录下的代码
$ mvn compile:testCompile
# 不同的插件一般都提供
$ mvn compile
2、官网
http://maven.apache.org/plugins/index.html
3、常见插件
1)maven-war-plugin
war包打包插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>web</warSourceDirectory>
<!-- 指定web.xml路径 -->
<webXml>web\WEB-INF\web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
2)maven-source-plugin
构建源码 JAR 包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<!--目标-->
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
<!-- 指定执行插件的时机 -->
<phase>package</phase>
</execution>
</executions>
</plugin>
三、模块化
1、继承
面向对象的思想中继承是为了提取共性,避免重复。而Maven的继承也是如此,将所有子模块共性的配置都可以统一放到父模块的pom文件中进行配置,不需要在每个子模块都配置一遍,这也是基于面向对象的思想。
(注意:父模块的pom.xml文件中的packaging必须设置为pom,即文档对象模型)
父模块pom.xml示例:
<groupId>edu.nf</groupId>
<artifactId>project-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<verison>${junit.version}</verison>
</dependency>
</dependencies>
这里将项目的一些属性配置以及junit都放到了父模块中配置。properties中可以设置项目的构建编码、JDK版本等配置。还可以统一所有依赖项目的版本号的管理。
子模块pom.xml示例:
<!-- 引用父模块 -->
<parent>
<artifactId>project-parent</artifactId>
<groupId>edu.nf</groupId>
<version>1.0-SNAPSHOT</version>
<!-- 可以省略不写 -->
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>project-module1</artifactId>
<packaging>jar</packaging>
在子模块需在<parent>
中配置父模块的GAV坐标,以及在<relativePath>
中设置父模块的pom文件的相对路径。而在父模块中配置的属性以及所有的依赖都会被子模块继承下来。子模块需要重新定义<artifactId>
的名称以及<packaging>
即可。
1)父项目:pom.xml - 对当前项目的描述
<!-- 定义父项目的 GAV ,注意:packaging必须为pom --> <groupId>edu.nf</groupId> <artifactId>project-parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!-- 根据需要,定义相关的属性和依赖 --> <!-- 这些属性和依赖都会被继承到子项目中 --> <properties> ... </properties> <dependencies> ... </dependencies>
2)子项目
<!-- 在子项目中父项目的 GAV 来引用父项目,从而实现继承关系 --> <parent> <groupId>edu.nf</groupId> <artifactId>project-parent</artifactId> <version>1.0-SNAPSHOT</version> <!-- 设置父项目的 pom 文件路径 --> <relativePath>../pom.xml</relativePath> </parent> <!-- 定义子项目的自己的GAV--> <!-- 子项目中的GAV默认与父项目的GAV一致 --> <artifactId>project-module1</artifactId> <packaging>jar</packaging> <!-- 子项目也会有属于自己的属性和依赖 --> <properties> ... </properties> <dependencies> ... </dependencies>
2、聚合
把多个项目整合在一起,方便操作。
可以在父模块中聚合所有的子模块,只需要在父模块的pom文件中将所有的子模块配置在<modules>
中,<modules>
中的每个<module>
分别指定各个子模块的名称。
父模块pom.xml示例:
<groupId>edu.nf</groupId>
<artifactId>project-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 聚合所有子模块 -->
<modules>
<module>project-module1</module>
<module>project-module2</module>
<module>project-module3</module>
</modules>
使用聚合的好处就是当构建整个项目的时候,不需要为每个子模块分别都构建一次,只需要在父模块(相当于整个项目)执行一次构建命令即可,此时会将所有的子模块一并进行构建。
<!-- 父项目把各个子项目聚合在一起,便于操作 --> <modules> <module>../demo-one</module> <module>../demo-two</module> </modules>
3、按需要依赖
有时候并不是所有个子模块都需要继承父类全部的依赖配置,不同的子模块可以根据需要分别继承不同的依赖配置,这时我们就可以在父模块中使用<dependencyManagement>
来管理所有依赖配置。
父模块pom.xml示例:
<groupId>edu.nf</groupId>
<artifactId>project-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
上面的junit依赖配置是放在<dependencyManagement>
中,这时所有的子模块并不会继承junit的依赖,各个子模块可以根据自身需要再对其进行依赖配置。
子模块pom.xml示例:
<parent>
<artifactId>project-parent</artifactId>
<groupId>edu.nf</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>project-module1</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
(注:子模块在依赖时只需要指定groupId和artifactId即可,不需要指定版本号)
第一:在父项目中,统一定义公共依赖,便于管理
<properties> <junit.version>4.13.2</junit.version> </properties> <!-- 依赖管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> </dependencies> </dependencyManagement>
第二:子项目,根据需要选择性的依赖父项目的依赖
<dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </dependencyManagement>
4、创建多模块项目
IDEA工具创建多模块以及各模块之间的依赖
创建多模块项目有许多优势和好处,包括:
- 模块化:多模块项目可以将应用程序分解为小而可管理的模块。这种模块化使得代码更容易理解、维护和扩展。每个模块都可以独立开发、测试和部署,而不会影响到其他模块。
- 代码重用:多模块项目可以鼓励代码重用。如果你需要在另一个项目中使用某些代码,你只需要将相应的模块导入到新项目中即可。
- 并行开发:多模块项目可以让多个团队或开发人员并行工作。每个团队或开发人员可以专注于自己的模块,并且可以在不影响其他模块的情况下进行开发和测试。
- 构建和部署:多模块项目可以让构建和部署变得更加容易。你可以将每个模块编译成一个独立的 jar 包或 war 包,然后在服务器上部署它们。
- 可维护性:多模块项目可以让代码更易于维护。由于每个模块都是独立的,你可以更容易地修改和更新其中的代码,而不会影响其他部分的代码。
综上所述,多模块项目可以提高应用程序的可维护性、可扩展性和可重用性。这些优势可以使得开发人员更加容易地构建和维护大型复杂的应用程序。