Maven(生命周期、POM、模块化、聚合、依赖管理)详解

Maven构建项目的生命周期

在Maven出现之前,项目构建的生命周期就已经存在,软件开发人员每天都在对项目进行清理,编译,测试,部署等工作,这个过程就是项目构建的生命周期。虽然大家都在不停的做构建工作,但公司与公司之间,项目与项目之间构建项目的方式有所不同。

Maven对所有的构建过程进行了抽象和统一。Maven构建项目的生命周期包含了项目清理,初始化,编译,测试,打包,集成测试,验证,部署和站点生成等几乎所有构建步骤

Maven的常用命令

mvn clean:调用clean生命周期的clean阶段,清理上一次构建项目生成的文件;

mvn compile :编译src/main/java中的java代码;

mvn test :编译并运行了test中内容 ;

mvn package:将项目打包成可发布的文件,如jar或者war包;

mvn install :发布项目到本地仓库 ;

POM

pom(Project Object Model)指的是项目对象模型,用来描述当前的maven项目。

Setting.xml文件主要用于配置maven的运行环境等一系列通用属性,是全局级别的配置文件,而pom.xml文件主要描述项目的maven坐标,依赖关系,开发者需要遵循的规则,组织等与项目相关的因素,是项目级别的配置文件。

依赖管理

依赖导入

就是对jar包的管理,以往我们需要下载好xxxx.jar的jar包,粘贴到工程的lib目录下面去,使用maven的依赖管理功能,想要引入某个包只需要导入maven的坐标即可(它会通过坐标找到对应的jar包并下载到本地的maven仓库)。

maven中央仓库地址:https://mvnrepository.com/

比方说我要导入junit的jar包,前往中央仓库搜索:junit

可以选择人数较多的版本:

随后复制它的坐标:

将坐标复制到我们项目的pom.xml文件中(注意要在dependencies)标签中:

依赖范围设置

在默认情况下,依赖可以在任何地方可用,可以通过<scope>标签设置作用的范围,作用范围主要有三种:

  1. 主程序范围有效(src/main)目录范围内
  2. 测试程序范围内有效(src/test)目录范围内
  3. 是否参与打包(package指令范围内)
依赖范围 编译源码 编译测试代码 测试运行 运行项目 示例
compile Y Y Y Y spring-web
test - Y Y - junit
provide Y Y Y - servlet-api
runtime - Y Y Y jdcb
system Y Y Y - 本地的jar包

依赖版本维护

如果pom文件中引入的依赖太多,各种依赖又有不同的版本,为了统一维护版本,我们可以将依赖的版本号抽取出来进行统一管理。具体操作的步骤如下:

  1. 在pom.xml中使用<propeties>属性定义jar包的版本。
  2. 在依赖的<version>中使用${}引入前面定义好的版本

依赖传递

当在项目中引入一个jar包时引入的jar包所依赖的jar也会跟着传递进来:

依赖冲突

一个项目可能会依赖多个库或模块,而这些库或模块又可能会依赖同一个类库的不同版本。当这些不同版本的类库被同时引入时,就会发生依赖冲突。

比如使用Maven导入了一个Servlet的包,当项目部署到Tomcat后产生了jar包冲突,因为在Tomcat服务器内置了servlet的jar。这就会造成依赖冲突。

解决依赖冲突的方法

  1. 使用maven提供的依赖调节原则(自动)
  2. 排除依赖,排除依赖的jar包
  3. 锁定版本
使用maven提供的依赖调节原则

第一声明者优先原则:

在pom.xml文件中,先声明哪个jar包,就以那个jar包为主。
路径近者优先原则:

优先使用我们自己导入的jar包,依赖中传递的jar包排其次,直接依赖高于间接依赖。

排除依赖,排除依赖的jar包

在<dependency>内导入jar包时,使用<exclusions>标签,在<exclusions>标签内使用<exclusion>包含需要排除的标签:

XML 复制代码
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.4.RELEASE</version>
        <!-- 排除依赖的jar包 -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
锁定版本

使用<dependencyManagement>(与dependencies同级):

XML 复制代码
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId></groupId>
                <artifactId></artifactId>
                <version></version>
            </dependency>
        </dependencies>
    </dependencyManagement>

设置好版本号后,无需在dependencies标签内再设置version:

项目模块化

Maven项目的模块化是一种将大型项目拆分成多个独立但相互关联的模块(Module)的方法。每个模块负责一部分功能,这样不仅可以提高项目的可维护性、可扩展性和可重用性,还能有效隔离各个模块之间的依赖,简化项目的管理。

Maven项目的继承

在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。

被继承的Maven工程是父工程,父工程的packaging的打包方式必须为pom
基础其他Maven工程为子过程,在pom.xml文件中通过parent标签进行父工程继承

Maven项目的聚合

在maven父工程的pom.xml文件中可以使用<modules>标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。


示例:

先创建一个工程,将packaging配置为pom,使它成为父工程:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.f</groupId>
    <artifactId>father</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

在目录下新建模块web,子模块的xml为:

可以看到自动有了parent标签

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.f</groupId>
        <artifactId>father</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>web</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

此时父工程自动添加了 <modules>标签:

相关推荐
Yeats_Liao27 分钟前
Navicat 导出表结构后运行查询失败ERROR 1064 (42000): You have an error in your SQL syntax;
数据库·sql
明月看潮生1 小时前
青少年编程与数学 02-007 PostgreSQL数据库应用 15课题、备份与还原
数据库·青少年编程·postgresql·编程与数学
明月看潮生1 小时前
青少年编程与数学 02-007 PostgreSQL数据库应用 14课题、触发器的编写
数据库·青少年编程·postgresql·编程与数学
空の鱼4 小时前
java开发,IDEA转战VSCODE配置(mac)
java·vscode
P7进阶路5 小时前
Tomcat异常日志中文乱码怎么解决
java·tomcat·firefox
小丁爱养花6 小时前
Spring MVC:HTTP 请求的参数传递2.0
java·后端·spring
CodeClimb6 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
等一场春雨6 小时前
Java设计模式 九 桥接模式 (Bridge Pattern)
java·设计模式·桥接模式
带刺的坐椅6 小时前
[Java] Solon 框架的三大核心组件之一插件扩展体系
java·ioc·solon·plugin·aop·handler
加酶洗衣粉6 小时前
MongoDB部署模式
数据库·mongodb