POM:(project boject model)项目对象模型

Maven 资源包管理器

  • 方便的依赖管理
  • 统一的项目结构
  • 跨平台标准的项目构建方式

运行原理:

依赖管理

pom.XML中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?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>org.example</groupId> <!---->组织名
<artifactId>untitled2</artifactId> /* 项目名 */<!---->
<version>1.0-SNAPSHOT</version> /* 版本号 */<!---->
<!-- -SNAPSHOT 是指快照版本 不稳定尚在开发 的意思 -->
<!-- 有其他值 -RELEASE 是指发行版本 功能稳定 -->
<!-- 例如 1.1-RELEASE 也可以省略 1.1 --->
<packaging>jar</packaging>
<!--打包方式 有 pom jar war 选项-->
<!---->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
<scope>compile</scope>

</dependency>
<!--更多依赖添加-->
<!-- <dependency>-->
<!--坐标信息-->
<!-- <groupId> 组织名</groupId>-->
<!-- <artifactId> 结构名 </artifactId>-->
<!-- <version>版本号</version>-->
<!-- <scope> </scope>-->
<!-- </dependency>-->


</dependencies>



<properties> <!--项目基本信息-->
<maven.compiler.source>18</maven.compiler.source><!--jdk版本-->
<maven.compiler.target>18</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>


<!--项目构建信息 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>

Maven Repository中搜索meavn的坐标信息

  • 组织名

    执行打包操作会把整个项目打包根据组织名写入meavn仓库

  • 版本号中

    • -SNAPSHOT 是指快照版本 不稳定尚在开发
    • -RELEASE是发行版本,功能稳定
    • 如果不指定 例如<version>1.1</version>默认发行版,相当于<version>1.1-RELEASE</version>
  • 在仓库中meavn根据一定格式的目录格式来定义jar包的路径,提供下载和查找、打包

    格式:groupId+"\"+artifactId+"\"+version+"\"+artifactId+"\"+version+.jar,其中groupId的.换为\

项目依赖

  • 直接依赖

    项目直接引入依赖

  • 间接依赖。

    通过依赖的项目中依赖的jar包进行依赖

如图上所示,项目A可以同时拥有A.jar、B.jar、C.jar

引入项目依赖示例

在项目A引入依赖B

1
2
3
4
5
 <dependency>
<groupId>com.example</groupId><!--组织名-->
<artifactId>example-dependency</artifactId><!--项目名-->
<version>1.0.0</version>
</dependency>

排除依赖

如果我想引入项目B的依赖,但是我又不想要项目B的某个依赖,该怎么办呢

在A项目的pom.xml中

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>com.example</groupId>
<artifactId>example-dependency</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.example</groupId>
<artifactId>excluded-library-C</artifactId>
</exclusion>
</exclusions>
</dependency>

项目B的pom.xml中

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>library-c</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>

此时A没有依赖c,B有依赖c,依赖c被项目A排除了

选择依赖

在项目B中选择依赖不让依赖传递 到 A ,B依旧可以使用依赖,但是依赖不会传递到A

在项目B中的pom.xml中

1
2
3
4
5
6
<dependency>
<groupId>com.example</groupId>
<artifactId>library-c</artifactId>
<version>1.0.0</version>
<optional>true</optional>
</dependency>

项目 A 并不会自动依赖于 library-c,除非在项目 A 的 POM 文件中显式声明。

依赖范围

在引入依赖的时候除了版本号、组织名和结构名外,还有一个<scope></scope>标签,他可以设定依赖的适用范围

主程序 测试程序 打包/运行 例子
compile(默认) log4j
test - - junit
provided - servlet-api
runtime - jdbc驱动
system × meavn以外的本地库
例如同项目其他模块
1
2
3
4
5
6
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
<scope>compile</scope>
</dependency>

生命周期

  • clean

    清理

  • default

    核心工作。编译,测试,打包,安装,部署。

  • site

    生成报告、发布站点

image-20240524220222327

同一套生命周期中,按照顺序一步步进行,运行后面的生命周期会运行前面的生命周期

生命周期均由插件完成

插件不满足所需开发需求,可通过pom.xml 里<plugins></plugins>单独配置

分模块设计

项目按照功能分为若干模块,方便项目的管理维护、扩展,方便模块之间互相调用,资源共享

我们可以把项目从以下的形式变为

1
2
3
4
|
|_项目
|
|___代码

这一类的形式

1
2
3
4
5
6
7
8
9
10
|
|_项目
|
|____模块
| |
| |____代码
|
|____模块
| |
| |____代码

拆分模块后,在开发的模块内引入pom想要引入的模块

1
2
3
4
5
<dependency>
<groupId>组织名</groupId>
<artifactId>模块名</artifactId>
<version>版本号</version>
</dependency>

这样做的话,在别的项目想使用该设计的方法就可以只引入一小部分代码而不是整个项目,例如Mybatis作为一个sql使用率广泛的框架只需要引入包就可以使用,而不是把原始的项目都引入进来。

继承

当多个模块都使用同一个依赖时,可以设置额外全新的一个父模块,让父模块支持这个依赖,要使用这个依赖的多个模块继承父模块

也能做到依赖管理

例如新建SpringBoot工程就继承自父模块

1
2
3
4
5
6
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

Meavn只能单继承,但是可以多重继承

因为SpringBoot默认已经有了继承,所以我们需要把父模块继承spring-boot-starter-parent子模块再继承父模块

步骤:

  1. 建立父模块,并设置打包方式为pom,继承spring-boot-starter-parent

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.6</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging> <!--打包方式-->
  2. 子模块设置继承没在<relativePath> 填写父模块pom.xml路径</relativePath>

    1
    2
    3
    4
    5
    6
    <parent>
    <groupId>com.example</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath> ../parent/pom.xml<!--相对路径--></relativePath>relativePath>
    </parent>
  1. 父模块配置依赖

    子模块会自动继承依赖

groupId会继承父模块的groupId

<relativePath>不指定会从远程仓库和本地仓库查找

子模块配置了相同的依赖不同的版本,以子模块为准(重写)

版本锁定

多个模块使用但是不是全部模块都使用的依赖,统一管理版本

步骤:

  1. 父模块使用<dependencyManagement></dependencyManagement>,在这里面引入依赖以及版本号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!--正常父模块依赖,被所有子模块继承-->
    <dependencies>
    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter-test</artifactId>
    <version>3.0.3</version>
    <scope>test</scope>
    </dependency>
    </dependencies>
    <!--子模块选择继承的模块,统一指定版本-->
    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>2.23.1</version>
    </dependency>
    </dependencies>
    </dependencyManagement>
  2. 子模块引入依赖,不需要指定版本号,没有引入依赖的不会引入父模块<dependencyManagement>里的依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j</artifactId>
    </dependency>
    <!--引入依赖,不需要输入版本号,由父模块统一指定-->

自定义属性

在依赖足够多,一个一个滑动查看<dependency></dependency>去查找,修改版本号很繁琐,可以自定义属性在一个界面内快速修改版本号

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    <properties>
<java.version>17</java.version>
<sptingBoot.version>3.0.3</sptingBoot.version>
<lombok.v>1.18.32</lombok.v>
</properties>


<!--名字可自定义,但是需要规范,不然认不出来-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${sptingBoot.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.v}</version>
</dependency>

聚合

如果使用继承、分模块设计的话,在打包项目某个模块时需要在本地模块找到继承的父模块和依赖的模块,如果没有会打包失败

需要一个一个的安装好模块到本地仓库,十分繁琐

聚合:把多个模块构成一个整体,完成项目的构建

聚合工程:不具备业务功能的空工程,只有一个pom.xml

打包方式为pom!!!

1
2
3
4
5
6
7
<packaging>pom</packaging>
<modules>
<module>../module1</module>
<module>../module1</module>
<module>所有项目想打包的相对的路径</module>
<module></module>
</modules>

此时这个聚合工程进行打包就完成了

私服

  1. 配置私服的访问用户名/密码

    打开本地meavn的setting.xml(apache-maven-3.9.6\conf\settings.xml),在<servers> </servers>写入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <servers>
    <server>
    <id>meavn-releases</id>
    <username>repouser</username>
    <password>repopwd</password>
    </server>
    <server>
    <id>meaven-snapshots</id>
    <username>repouser</username>
    <password>repopwd</password>
    </server>
    </servers>
  2. pom中配置上传地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        <distributionManagement>
    <snapshotRepository>
    <id>meaven-snapshots</id>
    <!-- id 名要与<server> </server> id名一致 -->
    <url>127.0.0.1/snapshots</url>
    </snapshotRepository>
    <repository>
    <id>meavn-releases</id>
    <url>127.0.0.1/releases</url>
    </repository>
    </distributionManagement>
  1. 设置私服依赖下载地址

    设置仓库组,把snapshots和releases等等仓库一起当为一个仓库组

配置的阿里云镜像仓库也是一个私服,只是公开出来了而已,所以要把阿里的<mirror></mirror>注释

也可以是使用<blocked>true</blocked>设置禁止使用,需要使用的时候在修改为false或者注释

settings.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<mirrors>

<mirror>
<id>meavn-public</id>
<mirrorOf>*</mirrorOf> <!--仓库的名字 *代表全选-->
<name>给程序员辨识信息的标签</name>
<url>url/repository/public/</url><!--公共仓库地址-->
</mirror>



<!--阿里云-->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
<blocked>true</blocked>
</mirror>
<!--默认-->
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
</mirrors>

<profiles></profiles>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<profile><!-- 注意没有s 在有s中间添加-->

<id>allow-snapshots</id>
<activation>
<activeByDefalt>true</activeByDefalt><!---指定该 profile 是否在默认情况下激活如果没有其他 profile 被显式激活或匹配条件被满足,则该 profile 会自动激活。-->
</activation>


<repositories>
<repository>
<id>meavn-public</id>
<url>url/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

</profile>

在meavn默认配置中有示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<profiles>

<profile>
<id>jdk-1.4</id> 指定 profile 的唯一标识符。Maven 使用该 ID 来引用这个 profile,便于管理多个 profile 配置。
<activation> 定义 profile 的激活条件。 有着 <os></os><property></property><file></file>等等条件
<jdk>1.4</jdk> 指定该 profile 应在何种 JDK 版本下激活。

<activeByDefault>true</activeByDefault>指定该 profile 是否在默认情况下激活如果没有其他 profile 被显式激活或匹配条件被满足,则该 profile 会自动激活。

</activation>

<repositories>
<repository>
<id>jdk14</id>指定该仓库的唯一标识符。Maven 使用该 ID 来引用这个仓库,便于管理多个仓库配置。
<name>Repository for JDK 1.4 builds</name> 为仓库指定一个人类可读的名称。
<url>http://www.myhost.com/maven/jdk14</url> 指定仓库的 URL。Maven 使用该 URL 来访问和下载依赖和插件。
<layout>default</layout> 指定仓库的布局类型,通常为 default。定义仓库的存储结构,default 是最常用的布局。
<snapshotPolicy>always</snapshotPolicy> 定义处理快照版本的策略。可以包括检查更新的频率、更新的模式等。
</repository>
</repositories>
</profile>



<profile>
<id>env-dev</id>

<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>

<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>

</profiles>

此外可以单独配置单个项目的仓库镜像

附录 常见指令

摘录30 个常用 Maven 命令 - 简书 (jianshu.com)

maven 命令除了常用的几个,大部分经常记不住,整理一下,方便查询。

maven 命令的格式为 mvn [plugin-name]:[goal-name],可以接受的参数如下,

  • D 指定参数,如 -Dmaven.test.skip=true 跳过单元测试;
  • P 指定 Profile 配置,可以用于区分环境;
  • e 显示maven运行出错的信息;
  • o 离线执行命令,即不去远程仓库更新包;
  • X 显示maven允许的debug信息;
  • U 强制去远程更新snapshot的插件或依赖,默认每天只更新一次。

常用maven命令

  • 创建maven项目:mvn archetype:create
    指定 group: -DgroupId=packageName
    指定 artifact:-DartifactId=projectName
    创建web项目:-DarchetypeArtifactId=maven-archetype-webapp
  • 创建maven项目:mvn archetype:generate
  • 验证项目是否正确:mvn validate
  • maven 打包:mvn package
  • 只打jar包:mvn jar:jar
  • 生成源码jar包:mvn source:jar
  • 产生应用需要的任何额外的源代码:mvn generate-sources
  • 编译源代码: mvn compile
  • 编译测试代码:mvn test-compile
  • 运行测试:mvn test
  • 运行检查:mvn verify
  • 清理maven项目:mvn clean
  • 生成eclipse项目:mvn eclipse:eclipse
  • 清理eclipse配置:mvn eclipse:clean
  • 生成idea项目:mvn idea:idea
  • 安装项目到本地仓库:mvn install
  • 发布项目到远程仓库:mvn:deploy
  • 在集成测试可以运行的环境中处理和发布包:mvn integration-test
  • 显示maven依赖树:mvn dependency:tree
  • 显示maven依赖列表:mvn dependency:list
  • 下载依赖包的源码:mvn dependency:sources
  • 安装本地jar到本地仓库:mvn install:install-file -DgroupId=packageName -DartifactId=projectName -Dversion=version -Dpackaging=jar -Dfile=path

web项目相关命令

  • 启动tomcat:mvn tomcat:run
  • 启动jetty:mvn jetty:run
  • 运行打包部署:mvn tomcat:deploy
  • 撤销部署:mvn tomcat:undeploy
  • 启动web应用:mvn tomcat:start
  • 停止web应用:mvn tomcat:stop
  • 重新部署:mvn tomcat:redeploy
  • 部署展开的war文件:mvn war:exploded tomcat:exploded

摘录maven常用命令大全(附详细解释)_mvn命令详解-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

mvn clean package -Dmaven.test.skip=true -- 跳过单测打包
mvn clean install -Dmaven.test.skip=true -- 跳过单测打包,并把打好的包上传到本地仓库
mvn clean deploy -Dmaven.test.skip=true -- 跳过单测打包,并把打好的包上传到远程仓库

mvn -v //查看版本
mvn archetype:create //创建 Maven 项目
mvn compile //编译源代码
mvn test-compile //编译测试代码
mvn test //运行应用程序中的单元测试
mvn site //生成项目相关信息的网站
mvn package //依据项目生成 jar 文件
mvn install //在本地 Repository 中安装 jar
mvn -Dmaven.test.skip=true //忽略测试文档编译
mvn clean //清除目标目录中的生成结果
mvn clean compile //将.java类编译为.class文件
mvn clean package //进行打包
mvn clean test //执行单元测试
mvn clean deploy //部署到版本仓库
mvn clean install //使其他项目使用这个jar,会安装到maven本地仓库中
mvn archetype:generate //创建项目架构
mvn dependency:list //查看已解析依赖
mvn dependency:tree com.xx.xxx //看到依赖树
mvn dependency:analyze //查看依赖的工具
mvn help:system //从中央仓库下载文件至本地仓库
mvn help:active-profiles //查看当前激活的profiles
mvn help:all-profiles //查看所有profiles
mvn help:effective -pom //查看完整的pom信息