返回

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包。

依赖引用方法

<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(内容未填补)

brew install maven

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

mvn -v

查看maven是否安装成功
查看maven是否安装成功

为依赖仓库添加镜像

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

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

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

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

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

image-20201231210536577
image-20201231210536577

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

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

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

更改依赖缓存目录

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

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

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

创建Maven项目

手动创建

创建一个文件夹

  • 目录树
/ #根目录
|-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)

<?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

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

nvm compile

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

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

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

指定项目main方法

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

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

查找依赖坐标

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

例如我们查找mysql的JDBC驱动

在Maven仓库中查找Mysql驱动
在Maven仓库中查找Mysql驱动

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

查找MySQL的具体依赖坐标
查找MySQL的具体依赖坐标

Eclipse中集成Maven

Maven中引入服务器

在Maven中引入Jetty服务器

更改pom.xml中的build标签

<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服务器

<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.46.22

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

iShot2021-01-02 23.48.19
iShot2021-01-02 23.48.19

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

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

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

iShot2021-01-02 23.50.31
iShot2021-01-02 23.50.31

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

image-20210103121908373
image-20210103121908373

创建子模块

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

iShot2021-01-02 23.53.46
iShot2021-01-02 23.53.46

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

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

iShot2021-01-03 13.51.40
iShot2021-01-03 13.51.40

iShot2021-01-02 23.58.42
iShot2021-01-02 23.58.42

iShot2021-01-02 23.59.19
iShot2021-01-02 23.59.19

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

iShot2021-01-03 00.03.12
iShot2021-01-03 00.03.12

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

iShot2021-01-03 13.59.49
iShot2021-01-03 13.59.49

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

image-20210103141325759
image-20210103141325759

Maven项目打包

项目开发的三种环境

  • 开发环境

  • 测试环境

  • 生产环境

为环境建立相应目录

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

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

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

为Maven引用打包配置

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

<!-- 开发环境的打包配置 -->
<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>标签中设置如何读取配置文件

<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属性

执行打包指令

clean compile package -Dmaven.test.skip=true

clean : 清除之前的编译结果

compile : 编译

package : 打包

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

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

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

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

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

完成打包

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

定义依赖范围

依赖冲突

comments powered by Disqus