Maven:项目对象模型

Maven简介

Maven是干什么的

Maven是Apache组织中的一个颇为成功的开源项目,Maven主要服务于基于java平台的项目构建,依赖管理和项目信息管理

约定 > 配置

构建工具

Ant(XML)

  • 最早的构建工具,基于IDE,2000年左右就流行的Java构建工具

  • 因为是基于XML脚本编写的,脚本xml文件特别大。

  • 对工程构建过程中的过程控制特别好

Maven(Java)

项目对象模型,通过其描述信息来管理项目的构建,报告和文档的软件项目管理工具。

它填补了Ant的缺点,Maven 第一次支持了从网络上下载的功能,仍然采用xml作为配置文件格式

Maven专注依赖管理,使用Java编写

Gradle(groovy)

结合了Ant和Maven的优点,继承了Ant的灵活和Maven的生命周期管理

被Google作为Android御用的管理工具,他最大的区别是不用xml作为配置文件格式,采用了DSL格式,使脚本更加灵活简洁

三种工具的区别

Ant 比较老,一般是一些传统的软件公司或企业在使用。Maven使用Java编写,是当下大多数互联网公司使用的一个构造工具,中文文档相对齐全。Gradle使用groovy编写,目前比较新型的构建工具一些初创的互联网公司会使用,有很大的使用空间

Maven四大特性

依赖管理系统、多模块构建、一致的项目结构、一致的构建模型和插件机制

依赖管理系统(Jar项目的多模块)

Maven为Java引入了一个新的依赖管理系统jar包管理,jar升级后更改配置文件即可

在Java中,可以使用groupIdartifactIdversion组成的Coordination(坐标)唯一标示一个依赖。任何基于Maven的项目自身也必须定义这三个属性,生成的包可以是Jar包,也可以是war包或者jar包。

依赖引用方法

1
2
3
4
5
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

Maven坐标为各种组件引入了秩序,任何一个组件都必须明确定义自己的坐标

  • groupId

    定义当前Maven项目隶属的实际项目-公司名称

    由于Maven中模块的概念,因此一个实际的项目,往往会被划分为很多模块。

    比如spring是一个实际项目,其对应的Maven模块会有很多,如spring-corespring-webmvc

  • artifactId

    该元素定义实际项目中胡一个Maven模块-项目名,推荐的做法是使用项目名称作为artifactId的前缀。

    比如spring-beanspring-webmvc

  • version

    该元素定义Maven项目当前所处的版本

多模块构建

(内容未填补)

一致性项目构建

Maven拥有一套自己的项目目录结构作为标准的Java项目结构,解决了使用不同IDE开发带来的目录不一致问题

Maven的设计理念就是 约定大于配置 (Conversion over configuration)

一致的构建模型和插件机制

  • 通过pom配置tomcat、jetty插件

安装Maven

Mac - brew安装 如何安装brew(内容未填补)

1
brew install maven

检查是否安装成功,查看maven版本信息

1
mvn -v

查看maven是否安装成功

为依赖仓库添加镜像

因为国内一些不可描述的原因,导致我们从Maven官方查找和拉取依赖的时候,可能会在网络上出现的一些问题。我们可以考虑通过修改Maven的一些配置,来访问国内的镜像仓库来加快我们的拉取速度

在查看maven信息时,我们可以看到通过brew安装的maven被安装到了下面这个目录中

/usr/local/Cellar/maven/3.6.3_1/libexec

我们进入目录查找,修改/conf/setting.xml文件中的内容

打开文件中,我们可以搜索mirrors找到下面这些信息

image-20201231210536577

根据阿里云Maven仓库的官网的相关信息,在mirrors标签中插入下面这段信息

1
2
3
4
5
6
7
<!-- 官方留下的那些注释不要动,在他们之后插入就可以 -->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

可以访问**阿里云Maven仓库**官网,查看具体的使用指南

更改依赖缓存目录

如果想将缓存的依赖存放到其他的位置,可以更改settings.xml文件中的<loaclRepository>中的地址

1
<loaclRepository>依赖存放目录</loaclRepository>

一般来讲大家的Mac都是一个盘,所以不用修改

创建Maven项目

手动创建

创建一个文件夹

  • 目录树
1
2
3
4
5
6
7
8
9
/ #根目录
|-src
| |-main #项目程序目录
| | |-java #项目java源码
| | |-resources #项目资源
| |-test #项目测试目录
| | |-java #项目的测试类
| | |-resources #测试使用的资源
|-pom.xml #Maven配置文件
  • 目录对应功能
目录 功能
/ 存放pom.xml及所有子目录
/src/main/java 项目的java源代码
/src/main/resources 项目的资源 property文件
/sec/test/java 项目的测试类 JUnit代码
/src/test/resources 测试使用的资源

创建pom.xml

POM(Project Object Model)

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
<?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>
<!--上面是Maven的声明文件,不用动-->

<!--公司名称-->
<groupId>com.xon</groupId>
<!--项目名称-->
<artifactId>mavenDemo</artifactId>
<!--版本号-->
<version>1.0.0</version>

<!--项目依赖-->
<dependencies>
<!--引用依赖-->
<dependency>
<!--定位项目组-->
<groupId>org.xon</groupId>
<!--定位项目名称-->
<artifactId>testOne</artifactId>
<!--定位项目版本-->
<version>1.0</version>
</dependency>
<!--引用另一个依赖-->
<dependency>
<groupId>org.xon</groupId>
<artifactId>testTwo</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
</project>

创建一个Java程序

/main/java目录下创建java项目,可以将此目录看做/src目录

简单建个HelloiWorld就好(内容未填补)

初始化Maven

启动终端,在项目的根目录运行代码

1
nvm compile

在运行成功以后会提示BUILD SUCCESS

在第一次初始化Maven时,会在网络上下载大量的资源,时间可能会比较长,请耐心等待,以后再运行就会好很多

在根目录也会多出一个target的文件夹,里面包含了相应java编译好的程序

指定项目main方法

1
mvn exec:java -Dexec.mainClass="com.xon.mavendemo.HelloWorld"

同样在终端项目根目录运行,同样耐性等待

查找依赖坐标

我们可以在Maven的官方仓库中找到所有的依赖和他们的坐标

例如我们查找mysql的JDBC驱动

在Maven仓库中查找Mysql驱动

我们点击我们想要的版本,在打开的页面就有相应的依赖坐标

查找MySQL的具体依赖坐标

Eclipse中集成Maven

Maven中引入服务器

在Maven中引入Jetty服务器

更改pom.xml中的build标签

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
<build>
<!-- 最终生成war包的名字 -->
<finalName>mavenDemo</finalName>
<!-- 插件 -->
<plugins>
<!-- 定位插件坐标,我这里找的是Jetty -->
<!-- https://mvnrepository.com/artifact/org.mortbay.jetty/jetty -->
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
<!-- 配置Jetty服务 -->
<configuration>
<!-- 设置java项目改动,服务自动刷新的时间间隔 -->
<scanIntervalSeconds>10</scanIntervalSeconds>
<!-- 设置项目的发布路径 -->
<contextPath>/demo</contextPath>
<connectors>
<!-- 定义服务端口号,不写默认8080 -->
<connector implementation="">
<port>8081</port>
</connector>
</connectors>
</configuration>
</plugins>
</build>

在Maven中引入Tomcat服务器

1
2
3
4
5
6
7
8
9
10
11
12
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8081</port>
<path>/demo</path>
<uriEncoding>UTF-8</uriEncoding>
<finalName>mavenDemo</finalName>
<server>tomcat7</server>
</configuration>
</plugin>

(内容未填补)- 因为Tomcat官方在7.0以后就停止了插件的支持,所以我实际实验以后才能给出详细的方法

Maven仓库的基本概念

Maven仓库就是存储Maven插件与jar包的文件位置,分为远程仓库与本地仓库

在Maven根据坐标查找构件的时候,首先在本地仓库中进行查找,如果没找到才会在远程仓库中查找,如果都没有找到,Maven就会报错

一般来说Maven项目目录下没有存放jar包的位置,使用的jar包都是通过配置文件从本地仓库中拉取的

远程仓库三种类型

中央仓库

是Maven默认的远程下载位置

私服

个人或公司搭建的私有仓库。一般用于节省公网带宽和时间,在局域网中搭建的私有仓库,用于代理所有外部的远程仓库

同时可以部署一些公司内部项目供其他项目使用

其他公共仓库

第三方的公共仓库,镜像仓库、社区仓库等非官方仓库

Maven环境下的多模块项目搭建

使用Maven环境下的多模块项目构建的特性完成Maven环境下多个模块的项目的管理与构建

我们用一个普通的JavaWeb项目来进行举例

我们知道一个JavaWeb项目分为Dao、Service与Web 三个层

我们将每一层拆分成一个单独的子模块,最终合并成一个项目来了解多模块的构建过程

创建根项目

根项目只用来整合子模块,所以内部不需要任何代码,只需要有pom.xml文件即可

为了规范Maven结构,我们新建一个原型,在里面写上我们的组名、项目名和版本号

创建新的原型

iShot2021-01-02 23.46.22

我们来选择项目名和文件存储位置

iShot2021-01-02 23.48.19

选择使用的Maven的版本和位置

我选择的是IDEA中内置的Maven,并且更改了aliyun的镜像,当然你也可以选择在下拉菜单中选择IDEA自动查找到的本地的Maven,或者在菜单中手动查找你下载的Maven目录

用户设置文件和本地存储库会自动根据你选择的Maven版本来改变

iShot2021-01-02 23.50.31

创建完成以后pom.xml中会自动生成我们的项目名和版本信息

image-20210103121908373

创建子模块

根项目创建完成以后,我们来创建子模块

iShot2021-01-02 23.53.46

我用dao包来模拟子模块,所以我选用quickstart原型来搭建我的java项目

如果是web模块,我们就选用web_app原型模版

iShot2021-01-03 13.51.40

iShot2021-01-02 23.58.42

iShot2021-01-02 23.59.19

创建完成以后,我们可以看到在父模块与子项目的pom.xml中都相互的引入的对应的信息

iShot2021-01-03 00.03.12

因为我们使用了原型模版,所以下方会自动编译,等待编译完成,我们可以看到项目已经完善了

iShot2021-01-03 13.59.49

我们把其他的子模块创建完成

image-20210103141325759

Maven项目打包

项目开发的三种环境

  • 开发环境

  • 测试环境

  • 生产环境

为环境建立相应目录

/src/resources目录中新建用于存储各种配置的文件夹

分别新建文件夹,并新建db.properties

  • /src/resouces/dev/db.properties(开发环境)
1
2
username=dev
password=dev1234
  • /src/resouces/test/db.properties(测试环境)
1
2
username=test
password=test1234
  • /src/resouces/product/db.properties(生产环境)
1
2
username=product
password=product1234

为Maven引用打包配置

在pom.xml中新建<profiles>标签中,没有

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
<!-- 开发环境的打包配置 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<!-- 指定为默认环境 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
<!-- 测试环境的打包配置 -->
<profiles>
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
</profiles>
<!-- 生产环境的打包配置 -->
<profiles>
<profile>
<id>product</id>
<properties>
<env>product</env>
</properties>
</profile>
</profiles>

为环境配置目录建立引用

<build>标签中设置如何读取配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<resources>
<resource>
<directory>src/main/resources/${env}</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>

$env对应打包时指定的 -P属性

执行打包指令

1
clean compile package -Dmaven.test.skip=true

clean : 清除之前的编译结果

compile : 编译

package : 打包

-Dmaven.test.skip=true : 跳过单元测试

1
clean compile package -Ptest -Dmaven.test.skip=true

-Pxxx : 指定配置文件,不指定为默认的环境(通过打包环境的<activation>定义默认环境)

xxx : 与读取配置中的$env对应

因为执行了clean指令,所以会覆盖掉以前的打包文件

完成打包

执行命令以后,会在/target中生成.war的包,用解压软件解压以后,可以在/WEB-INF/classes目录中看到db.properties中为我们指定的环境的db.properties

定义依赖范围

依赖冲突

请我喝杯咖啡吧~

支付宝
微信