Maven

1. Maven 是什么

Maven 是一个项目管理工具,它包含了一个项目对象模型(Project Object Model),反映在配置中,就是一个 pom.xml 文件。是一组标准集合,一个项目的生命周期、一个依赖管理系统,另外还包括定义在项目生命周期阶段的插件(plugin)以及目标(goal)。

当我们使用 Maven 的使用,通过一个自定义的项目对象模型,pom.xml 来详细描述我们自己的项目。

Maven 中的有两大核心:

  • 依赖管理:对 jar 的统一管理(Maven 提供了一个 Maven 的中央仓库,https://mvnrepository.com/,当我们在项目中添加完依赖之后,Maven 会自动去中央仓库下载相关的依赖,并且解决依赖的依赖问题)
  • 项目构建:对项目进行编译、测试、打包、部署、上传到私服等

2. Maven 安装

Maven 是 Java 项目,因此必须先安装 JDK。

2-1.png

下载 Maven:下载地址:http://maven.apache.org/download.cgi

2-2.png

  • 解压并配置

2-3.png

配置,只需要配置环境变量即可:

首先配置 MAVEN_HOME:

2-4.png

然后配置环境变量:

2-5.png

  • 检验安装

2-6.png

如果使用了 IntelliJ IDEA ,可以不用去额外下载 Maven,直接使用 IDEA 中自带的 Maven 插件即可。IntelliJ IDEA 中自带的 Maven 插件在 \ideaIU-2019.2.4.win\plugins\maven\lib\maven3

3. Maven 配置

maven的conf目录中有 settings.xml ,是maven的配置文件,实际上,没有特殊需求的话,安装好之后直接就可以用了。一般来说,还是需要稍微配置一下,

  • Maven默认使用国外的中央仓库,下载依赖速度过慢,所以都会配置一个国内的公共仓库(阿里巴巴的仓库)替代中央仓库。
  • 我们可以自定义一个目录作为本地仓库,Maven下载的所有依赖都会保存在这个目录中。
  • 配置私服 ,如果公司搭建了的自己 Maven 私服 (这个仓库中存放 一般就是公司内部自己开发的 jar)这时我们就要配置私服让他去私服下载依赖。

我现在用的settings.xml

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <!-- 本地仓库的位置 -->
    <localRepository>F:/repository</localRepository>
  
    <!-- Apache Maven 配置 -->
    <pluginGroups/>
    <proxies/>

    <!-- 私服发布的用户名密码 -->
    <servers>
        <server>
            <id>releases</id>
            <username>deployment</username>
            <password>He2019</password>
        </server>
        <server>
            <id>snapshots</id>
            <username>deployment</username>
            <password>He2019</password>
        </server>
    </servers>
    
    <!-- 阿里云镜像 -->
    <mirrors>
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <!-- https://maven.aliyun.com/repository/public/ -->
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

    <!-- 配置: java8, 先从阿里云下载, 没有再去私服下载  -->
    <!-- 20190929 hepengju 测试结果: 影响下载顺序的是profiles标签的配置顺序(后面配置的ali仓库先下载), 而不是activeProfiles的顺序 -->
    <profiles>
        <!-- 全局JDK1.8配置 -->
        <profile>
            <id>jdk1.8</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
            </activation>
            <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
            </properties>
        </profile>

        
        <!-- Nexus私服配置: 第三方jar包下载, 比如oracle的jdbc驱动等 -->
        <profile>
            <id>dev</id>
            <repositories>
                <repository>
                    <id>nexus</id>
                    <url>http://nexus.hepengju.cn:8081/nexus/content/groups/public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>public</id>
                    <name>Public Repositories</name>
                    <url>http://nexus.hepengju.cn:8081/nexus/content/groups/public/</url>
                </pluginRepository>
            </pluginRepositories>
        </profile>
        
        <!-- 阿里云配置: 提高国内的jar包下载速度 -->
        <profile>
            <id>ali</id>
            <repositories>
                <repository>
                    <id>alimaven</id>
                    <name>aliyun maven</name>
                    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>alimaven</id>
                    <name>aliyun maven</name>
                    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
                </pluginRepository>
            </pluginRepositories>
        </profile>

    </profiles>
    
    <!-- 激活配置 --> 
    <activeProfiles>
        <activeProfile>jdk1.8</activeProfile>
        <activeProfile>dev</activeProfile>
        <activeProfile>ali</activeProfile>
    </activeProfiles>
</settings>

仓库类型

仓库类型说明
本地仓库就是你自己电脑上的仓库,每个人电脑上都有一个仓库,默认位置在 当前用户名\.m2\repository
私服仓库公司可以通过 Nexus来创建、管理一个私服,不对外开发。
中央仓库有 Apache 团队来维护,包含了大部分的 jar,

现在存在 3 个仓库,那么 jar 包如何查找呢?

3-1.png

4. Maven 常用命令

Maven 中有一些常见的命令,如果使用 Eclipse 需要手动敲命令,如果使用 IDEA 的话,可以不用命令,直接点点点就可以了。

常用命令中文含义说明
mvn clean清理这个命令可以用来清理已经编译好的文件
mvn compile编译将 Java 代码编译成 Class 文件
mvn test测试项目测试
mvn package打包根据用户的配置,将项目打成 jar 包或者 war 包
mvn install安装手动向本地仓库安装一个 jar
mvn deploy上传将 jar 上传到私服

这里需要注意的是,这些命令都不是独立运行的,它有一个顺序。举个简单例子:

我想将 jar 上传到私服,那么就要构建 jar,就需要执行 package 命令,要打包,当然也需要测试,那就要走 mvn test 命令,要测试就要先编译……,因此,最终所有的命令都会执行一遍。不过,开发者也可以手动配置不执行某一个命令,这就是跳过。一般来是,除了测试,其他步骤都不建议跳过。

当然,如果开发者使用了 IDEA ,这些命令不用手动敲,点一下就行:

4-1.png

5、Idea-Maven


在Idea中关联Maven

在idea中关联本地安装的maven,后续就可以通过idea使用maven,管理项目啦。

在全局设置中,关联Maven
idea关联maven

创建Maven项目

如下选项
创建maven项目1
设置项目名
创建maven项目2
项目位置如下
创建maven项目3
项目结构如下:
创建maven项目5

6. Maven 依赖管理

Maven 项目,如果需要使用第三方的控件,都是通过依赖管理来完成的。这里用到的一个东西就是 pom.xml 文件,概念叫做项目对象模型(POM,Project Object Model),

Maven 坐标

<dependencies>                      //在 dependencies 标签中,添加项目需要的 jar 所对应的 maven 坐标。
  <dependency>                      //一个 dependency 标签表示一个坐标
    <groupId>junit</groupId>        //groupId 团体、公司、组织机构等等的唯一标识。团体标识的约定是它以创建这个项目的组                                       织名称的逆向域名。如 apache 的 groupId 是 org.apache.
    <artifactId>junit</artifactId>  //artifactId 相当于在一个组织中项目的唯一标识符。
    <version>4.11</version>         //version项目的版本。一个项目可能会有多个版本。如果是正在开发的项目,我们可以给                                         版本号加上一个 SNAPSHOT,表示这是一个快照版(新建项目的默认版本号就是快照版)
    <scope>test</scope>             //scope:表示依赖的使用范围
  </dependency>
</dependencies>

scope:表示依赖范围。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2DuyztDg-1631030255573)(C:/Users/Administrator/Desktop/%E5%B8%B8%E7%94%A8%E6%96%87%E4%BB%B6/%E7%AC%94%E8%AE%B0/%E7%AC%94%E8%AE%B02/Redis/Pictures/6-1.png)]

我们添加了很多依赖,但是不同依赖的使用范围是不一样的。最典型的有两个,一个是数据库驱动,另一个是单元测试。

  • 数据库驱动,在使用的过程中,我们自己写代码,写的是 JDBC 代码,只有在项目运行时,才需要执行 MySQL 驱动中的代码。所以,MySQL 驱动这个依赖在添加到项目中之后,可以设置它的 scope 为 runtime,编译的时候不生效。

  • 单元测试,只在测试的时候生效,所以可以设置它的 scope 为 test,这样,当项目打包发布时,单元测试的依赖就不会跟着发布。

依赖冲突

  • 依赖冲突产生的原因:在项目开发中使用Maven管理Jar包时,常常会遇到Jar包依赖冲突。其根本原因是不同Jar包引用了同一Jar包的不同版本。

6-2.png

当系统编译加载时,由于maven对jar包的依赖次序不同,系统可能编译加载 c.jar(1.2版本) ,也可能编译加载 c.jar(1.4版本) 。

  • 当编译加载c.jar(1.4版本) 时,由于很多 jar 包都支持向下兼容,即高版本兼容低版本,因此不论 d.jar 调用 c.jar 还是 b.jar 调用 c.jar 一般都不会出问题。
  • 当编译加载c.jar(1.2.版本) 时,那么 b.jar 调用Method A() 时则会报 NoSuchMethodError 异常,因为 Method A() 函数只存在于高版本的 c.jar 中,而此时系统编译加载的却是低版本的 c.jar 。上面所描述的情况便是所谓的依赖冲突问题。

冲突解决

  1. 先定义先使用
  2. 路径最近原则(直接声明使用)

以 spring-context 为例,下图中 x 表示失效的依赖(优先级低的依赖,即路径近的依赖优先使用):

6-3.png

上面这两条是默认行为。

我们也可以手动控制。手动控制主要是通过排除依赖来实现,如下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.9.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这个表示从 spring-context 中排除 spring-core 依赖。

7. Maven 私服

Maven 仓库管理也叫 Maven 私服或者代理仓库。使用 Maven 私服有两个目的:

  1. 私服是一个介于开发者和远程仓库之间的代理
  2. 私服可以用来部署公司自己的 jar

Nexus 介绍

Nexus 是一个强大的 Maven 仓库管理工具,使用 Nexus 可以方便的管理内部仓库同时简化外部仓库的访问。官网是:https://www.sonatype.com/

安装

  • 下载

下载地址:https://www.sonatype.com/download-oss-sonatype

  • 解压

将下载下来的压缩包,拷贝到一个没有中文的路径下,然后解压。

  • 启动

解压之后,打开 cmd 窗口(以管理员身份打开 cmd 窗口),然后定位了 nexus 解压目录,执行 nexus.exe/run 命令启动服务。

7-1.png

这个启动稍微有点慢,大概有 1 两分钟的样子

启动成功后,浏览器输入 http://lcoalhost:8081 打开管理页面。

打开管理页面后,点击右上角上的登录按钮进行登录,默认的用户名/密码是 admin/admin123。当然,用户也可以点击设置按钮,手动配置其他用户。

7-2.png

点击 Repositories 可以查看仓库详细信息:

7-3.png

仓库类型

名称说明
proxy表示这个仓库是一个远程仓库的代理,最典型的就是代理 Maven 中央仓库
hosted宿主仓库,公司自己开发的一些 jar 存放在宿主仓库中,以及一些在 Maven 中央仓库上没有的 jar
group仓库组,包含代理仓库和宿主仓库
virtual虚拟仓库

上传 jar

上传 jar,配置两个地方:

  • Maven 的 conf/settings.xml 文件配置:
<server>
  <id>releases</id>
  <username>admin</username>
  <password>admin123</password>
</server>
<server>
  <id>snapshots</id>
  <username>admin</username>
  <password>admin123</password>
</server>

在要上传 jar 的项目的 pom.xml 文件中,配置上传路径:

<distributionManagement>
    <repository>
        <id>releases</id>
        <url>http://localhost:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>snapshots</id>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

配置完成后,点击 deploy 按钮,或者执行 mvn deploy 命令就可以将 jar 上传到私服上。

下载私服上的 jar

直接在项目中添加依赖,添加完成后,额外增加私服地址即可:

<repositories>
    <repository>
        <id>local-repository</id>
        <url>http://localhost:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

8. 聚合工程

所谓的聚合工程,实际上也就是多模块项目。在一个比较大的互联网项目中,项目需要拆分成多个模块进行开发,比如订单模块、VIP 模块、支付模块、内容管理模块、CMS、CRM 等等。这种拆分方式,实际上更接近于微服务的思想。在一个模块中,还可以继续进行拆分,例如分成 dao、service、controller 等。

有人可能会说,这个分包不就行了吗?

小项目当然可以分包,大项目就没法分包了。比如,在一个大的电商系统中,有一个子模块叫做用户管理、还有一个子模块叫做订单管理,这两个子模块都涉及到用户,像这种情况,我们就需要将用户类单独提取出来,做成单独的模块,供其他模块调用。

多模块项目展示

|--javaboy-parent
      |-- javaboy-cms
      |-- javaboy-crm
      |-- javaboy-manger
           |-- javaboy-manager-model
           |-- javaboy-manager-dao
           |-- javaboy-manager-service
           |-- javaboy-manager-web

以 javaboy-manger 为例,javaboy-manager 本身并不提供功能,它只负责管理他自己的子模块,而他的子模块每一个都无法独立运行,需要四个结合在一起,才可以运行。项目打包时,model、dao、service 都将打包成 jar,然后会自动将打包好的 jar 复制到 web 中,再自动将 web 打包成 war 包。

IDEA 中创建聚合工程

1.创建一个空的 Maven 项目:

8-1.png

项目创建完成后,由于 parent 并不参与业务的实现,只是用来管理它的子模块,因此,src 目录可以将其删除。

8-2.png

2.选中当前工程,右键单击,New->Module

8-3.png

然后继续选择创建一个 Maven 项目:

8-4.png

在 IDEA 中,已经默认指明了当前 Module 的 parent,开发者只需要填入当前 Module 的 artifactId 即可:

8-5.png

javaboy-manager 创建完成后,此时,观察 javaboy-parent 的 pom.xml 文件,发现它自动加上了 packing 属性:

8-6.png

其中,它的 packaging 属性值为 pom,这表示它是一个聚合工程,同时,他还多了 modules 节点,指明了它自己的子模块。 同时,注意 javaboy-manager ,它自身多了一个 parent 节点,这个 parent 节点描述了它的父模块的属性值:

<parent>
    <artifactId>javaboy-parent</artifactId>
    <groupId>org.javaboy</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

这个 parent 不仅仅是一个简单的父子关系描述,它存在继承关系,一般我们可以在 parent 中统一定义依赖或者插件的版本号

3.由于 javaboy-manager 本身也是一个聚合工程,因此,javaboy-manager 的 src 目录也可以删除。

8-7.png

4.选中 javaboy-manager,右键单击,New->Module 创建一个新的 Maven 模块出来。这个步骤类似于第二步,不在赘述。 这里,新的 javaboy-manager-model 创建成功后,我们手动配置它的 packaging 属性值为 jar。

8-8.png

5.依照第 4 步,再分别创建 javaboy-manager-service 以及 javaboy-manager-dao

6.继续创建 javaboy-manager-web 模块,不同于其他模块,web 模块需要打包成 war。

7.web 工程创建完成后,完善模块之间的继承关系。

javaboy-manager-web 依赖 javaboy-manager-service javaboy-manager-service 依赖 javaboy-manager-dao javaboy-manager-dao 依赖 javaboy-manager-model

注意,依赖默认是有传递性的,即在 javaboy-manager-dao 中依赖了 javaboy-manager-model,在 javaboy-manager-service 也能访问到。

配置后的依赖关系如下图:

8-9.png

有一个需要注意的地方,在多模块项目中,web 项目打包需要注意以下问题:

  1. 不可以直接单独打包
  2. 如果要打包,有两种方式:
  • 第一种就是先手动挨个将 model、dao、service 安装到本地仓库
  • 从聚合工程处打包,即从 web 的parent 处打包。

9.常见错误

Maven依赖爆红

找到本地仓库中的jar包,将仓库中的_remote.repositorieslastUpdate文件删掉,然后对该模块进行reimport操作,然后关闭idea,重新打开,就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值