乐趣区

关于java:Maven实战与原理分析二maven实战

 

1 Maven 介绍

1.1 为什么应用 Maven

因为 Java 的生态十分丰盛,无论你想实现什么性能,都能找到对应的工具类,这些工具类都是以 jar 包的模式呈现的,例如 Spring,SpringMVC、MyBatis、数据库驱动,等等,都是以 jar 包的模式呈现的,jar 包之间会有关联,在应用一个依赖之前,还须要确定这个依赖所依赖的其余依赖,所以,当我的项目比拟大的时候,依赖治理会变得十分麻烦臃肿,这是 Maven 解决的第一个问题。

Maven 还能够解决多模块我的项目。简略的我的项目,单模块分包解决即可,如果我的项目比较复杂,要做成多模块我的项目,例如一个电商我的项目有订单模块、会员模块、商品模块、领取模块 …,一般来说,多模块我的项目,每一个模块无奈独立运行,要多个模块合在一起,我的项目才能够运行,这个时候,借助 Maven 工具,能够实现我的项目的一键打包。

Maven 之前,咱们更多的是应用 Ant 的我的项目构建工具,Ant 有一个特点,每次都得写,每次都写的差不多,配置也臃肿。所以,起初搞进去 Maven。Maven 就是最先进的版本构建工具吗?不是的,只不过,目前在 Java 畛域 Maven 应用比拟多。除了 Maven,还有 Gradle。

1.2 Maven 是什么

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

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

Maven 中的有两大外围:

  • 依赖治理:对 jar 的对立治理(Maven 提供了一个 Maven 的地方仓库,mvnrepository.com/,当咱们在我的项目中增加完… 会主动去地方仓库下载相干的依赖,并且解决依赖的依赖问题)
  • 我的项目构建:对我的项目进行编译、测试、打包、部署、上传到私服等

2. Maven 装置

  • Maven 是 Java 我的项目,因而必须先装置 JDK。

下载 Maven:

  • 下载 Maven

下载地址:maven.apache.org/download.cg…

  • 解压并配置

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

首先配置 MAVEN_HOME:

而后配置环境变量:

  • 测验装置

如果应用了 IntelliJ IDEA,能够不必去额定下载 Maven,间接应用 IDEA 中自带的 Maven 插件即可。IntelliJ IDEA 中自带的 Maven 插件在 \ideaIU-2019.2.4.win\plugins\maven\lib\maven3

3. Maven 配置

实际上,没有非凡需要的话,装置好之后间接就能够用了。一般来说,还是须要略微配置一下,比方地方仓库的问题。默认应用 Maven 本人的地方仓库,应用起来网速比较慢,这个时候,能够通过批改配置文件,将仓库改成国内的镜像仓库,国内仓库应用较多的是阿里巴巴的仓库。

3.1 仓库类型

仓库类型 阐明
本地仓库 就是你本人电脑上的仓库,每个人电脑上都有一个仓库,默认地位在 以后用户名 \.m2\repository
私服仓库 一般来说是公司外部搭建的 Maven 私服,处于局域网中,访问速度较快,这个仓库中寄存的 jar 个别就是公司外部本人开发的 jar
地方仓库 有 Apache 团队来保护,蕴含了大部分的 jar,晚期不蕴含 Oracle 数据库驱动,从 2019 年 8 月开始,蕴含了 Oracle 驱动

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

3.2 本地仓库配置

本地仓库默认地位在 以后用户名 \.m2\repository,这个地位能够自定义,然而不倡议大家自定义这个地址,有几个起因:

  1. 尽管所有的本地的 jar 都放在这个仓库中,然而并不会占用很大的空间。
  2. 默认的地位比拟荫蔽,不容易碰到

技术上来说,当然是能够自定义本地仓库地位的,在 conf/settings.xml 中自定义本地仓库地位:

3.3 近程镜像配置

因为默认的地方仓库下载较慢,因而,也能够将近程仓库地址改为阿里巴巴的仓库地址:

<mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
复制代码

这段配置,加在 settings.xml 中的 mirrors 节点中:

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 通过命令来构建我的项目

能够间接通过命令来构建一个 Maven 我的项目,不过在理论开发中,个别应用 Eclipse 或者 IDEA 就能够间接创立 Maven 我的项目了。

创立命令:

mvn archetype:generate -DgroupId=org.javaboy -DartifactId=firstapp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
复制代码

看到如下提醒,示意我的项目创立胜利:

我的项目创立胜利后,就两个文件:

阐明对一个任何一个我的项目而言,最最外围的就是这两个。

pom.xml 中,则定义了所有的我的项目配置。

4.2 对我的项目进行打包

接下来,咱们通过 mvn package 命令能够将刚刚创立的我的项目打成一个 jar 包。

在打包之前,须要配置 JDK 的版本至多为 7 以上,因而,咱们还须要手动批改一下 pom.xml 文件,即增加如下配置:

增加实现后,执行打包命令,留神执行所有命令时,命令行要定位到 pom.xml 文件所在的目录,看到如下提醒,示意我的项目打包胜利。

4.3 将我的项目装置到本地仓库

如果须要将我的项目装置到本地仓库,能够间接执行 mvn install 命令,留神,mvn install 命令会蕴含下面的 mvn package 过程。

装置到本地仓库之后,这个时候,点开本人的本地仓库,就能够看到相干的 jar 了。

5. IDEA 中应用 Maven

不同于 Eclipse,IDEA 装置实现后,就能够间接应用 Maven 了。

5.1 Maven 相干配置

IDEA 中,Maven 的配置在 File->Settings->Build,Execution,Deployment->Build Tools->Maven:

5.2 JavaSE 工程创立

首先在创立一个工程时,抉择 Maven 工程:

如果勾选上 Create from archetype,则示意能够依据一个我的项目骨架(我的项目模板)来创立一个新的工程,不过,如果只是创立 JavaSE 我的项目,则不必抉择我的项目骨架。间接 Next 即可。而后填入我的项目的坐标,即 groupId 和 artifactId。

填完之后,间接 Next 即可。这样,咱们就会获取一个 JavaSE 工程,我的项目构造和你用命令创立进去的我的项目截然不同。

5.3 JavaWeb 工程创立

在 IDEA 中,创立 Maven Web 我的项目,有两种思路:

  • 首先创立一个 JavaSE 我的项目,而后手动将 JavaSE 我的项目革新成一个 JavaWeb 我的项目
  • 创立我的项目时抉择我的项目骨架,骨架就抉择 webapp

两种形式中,举荐应用第一种形式。

5.3.1 革新 JavaSE 我的项目

这种形式,首先创立一个 JavaSE 我的项目,创立步骤和下面的统一。

我的项目创立实现后,首先批改 pom.xml,配置我的项目的打包格局为 war 包。 这样,IDEA 就晓得以后我的项目是一个 Web 我的项目:

而后,选中 JavaSE 工程,右键单击,抉择 Open Module Settings,或者间接按 F4,而后抉择 Web,如下图:

接下来,在 webapp 目录中,增加 web.xml 文件。

留神,肯定要批改 web.xml 文件地位:

配置实现后,点击 OK 退出。

我的项目创立实现后,接下来就是部署了。

部署,首先点击 IDEA 右上角的 Edit Configurations:

而后,配置 Tomcat:

接下来抉择 Deployment 选项卡,配置要公布的我的项目:

最初,点击 IDEA 右上角的三角符号,启动我的项目。

5.3.2 通过 webapp 骨架间接创立

这种形式比较简单,基本上不须要额定的配置,我的项目创立实现后,就是一个 web 我的项目。只须要咱们在创立我的项目时,抉择 webapp 骨架即可。

抉择骨架之后,前面的步骤和前文统一。

我的项目创立胜利后,只有 webapp 目录,这个时候,本人手动创立 java 和 resources 目录,创立实现后,右键单击,抉择 Mark Directory As,将 java 目录标记为 sources root,将 resources 目录标记为 resources root 即可。

但凡在 IDEA 右下角看到了 Enable Auto Import 按钮,肯定点一下

6. Maven 依赖治理

Maven 我的项目,如果须要应用第三方的控件,都是通过依赖治理来实现的。这里用到的一个货色就是 pom.xml 文件,概念叫做我的项目对象模型(POM,Project Object Model),咱们在 pom.xml 中定义了 Maven 我的项目的模式,所以,pom.xml 相当于是 Maven 我的项目的一个地图。就相似于 web.xml 文件用来形容三大 web 组件一样。

这个地图中都波及到哪些货色呢?

6.1 Maven 坐标

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    junit
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
</dependencies>
复制代码
  • dependencies

在 dependencies 标签中,增加我的项目须要的 jar 所对应的 maven 坐标。

  • dependency

一个 dependency 标签示意一个坐标

  • groupId

个人、公司、组织机构等等的惟一标识。个人标识的约定是它以创立这个我的项目的组织名称的逆向域名(例如 org.javaboy)结尾。一个 Maven 坐标必须要蕴含 groupId。一些典型的 groupId 如 apache 的 groupId 是 org.apache.

  • artifactId

artifactId 相当于在一个组织中我的项目的惟一标识符。

  • version

一个我的项目的版本。一个我的项目的话,可能会有多个版本。如果是正在开发的我的项目,咱们能够给版本号加上一个 SNAPSHOT,示意这是一个快照版(新建我的项目的默认版本号就是快照版)

  • scope

示意依赖范畴。

咱们增加了很多依赖,然而不同依赖的应用范畴是不一样的。最典型的有两个,一个是数据库驱动,另一个是单元测试。

数据库驱动,在应用的过程中,咱们本人写代码,写的是 JDBC 代码,只有在我的项目运行时,才须要执行 MySQL 驱动中的代码。所以,MySQL 驱动这个依赖在增加到我的项目中之后,能够设置它的 scope 为 runtime,编译的时候不失效。

单元测试,只在测试的时候失效,所以能够设置它的 scope 为 test,这样,当我的项目打包公布时,单元测试的依赖就不会跟着公布。

6.2 依赖抵触

  • 依赖抵触产生的起因

在图中,a.jar 依赖 b.jar,同时 a.jar 依赖 d.jar,这个时候,a 和 b、d 的关系是间接依赖的关系,a 和 c 的关系是间接依赖的关系。

6.2.1 抵触解决

  1. 先定义先应用
  2. 门路最近准则(间接申明应用)

以 spring-context 为例,下图中 x 示意生效的依赖(优先级低的依赖,即门路近的依赖优先应用):

下面这两条是默认行为。

咱们也能够手动管制。手动管制次要是通过排除依赖来实现,如下:

<dependency>
    <groupId>org.springframework</groupId>
    spring-context
    <version>5.1.9.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            spring-core
        </exclusion>
    </exclusions>
</dependency>
复制代码

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

7. Maven 私服

Maven 仓库治理也叫 Maven 私服或者代理仓库。应用 Maven 私服有两个目标:

  1. 私服是一个介于开发者和近程仓库之间的代理
  2. 私服能够用来部署公司本人的 jar

7.1 Nexus 介绍

Nexus 是一个弱小的 Maven 仓库管理工具,应用 Nexus 能够不便的治理外部仓库同时简化内部仓库的拜访。官网是:www.sonatype.com/

7.2 装置

  • 下载

下载地址:www.sonatype.com/download-os…

  • 解压

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

  • 启动

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

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

启动胜利后,浏览器输出 http://lcoalhost:8081 关上治理页面。

关上治理页面后,点击右上角上的登录按钮进行登录,默认的用户名 / 明码是 admin/admin123。当然,用户也能够点击设置按钮,手动配置其余用户。

点击 Repositories 能够查看仓库详细信息:

7.2.1 仓库类型

名称 阐明
proxy 示意这个仓库是一个近程仓库的代理,最典型的就是代理 Maven 地方仓库
hosted 宿主仓库,公司本人开发的一些 jar 寄存在宿主仓库中,以及一些在 Maven 地方仓库上没有的 jar
group 仓库组,蕴含代理仓库和宿主仓库
virtual 虚构仓库

7.2.2 上传 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 上传到私服上。

7.2.3 下载私服上的 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 等。

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

小我的项目当然能够分包,大我的项目就没法分包了。比方,在一个大的电商零碎中,有一个子模块叫做用户治理、还有一个子模块叫做订单治理,这两个子模块都波及到用户,像这种状况,咱们就须要将用户类独自提取进去,做成独自的模块,供其余模块调用。

8.1 多模块我的项目展现

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

8.2 IDEA 中创立聚合工程

1. 创立一个空的 Maven 我的项目:

我的项目创立实现后,因为 parent 并不参加业务的实现,只是用来治理它的子模块,因而,src 目录能够将其删除。

2. 选中以后工程,右键单击,New->Module

而后持续抉择创立一个 Maven 我的项目:

在 IDEA 中,曾经默认指明了以后 Module 的 parent,开发者只须要填入以后 Module 的 artifactId 即可:

javaboy-manager 创立实现后,此时,察看 javaboy-parent 的 pom.xml 文件,发现它主动加上了 packing 属性:

其中,它的 packaging 属性值为 pom,这示意它是一个聚合工程,同时,他还多了 modules 节点,指明了它本人的子模块。同时,留神 javaboy-manager,它本身多了一个 parent 节点,这个 parent 节点形容了它的父模块的属性值:

<parent>
    javaboy-parent
    <groupId>org.javaboy</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
复制代码

这个 parent 不仅仅是一个简略的父子关系形容,它存在继承关系,个别咱们能够在 parent 中对立定义依赖或者插件的版本号

3. 因为 javaboy-manager 自身也是一个聚合工程,因而,javaboy-manager 的 src 目录也能够删除。

4. 选中 javaboy-manager,右键单击,New->Module 创立一个新的 Maven 模块进去。这个步骤相似于第二步,不在赘述。这里,新的 javaboy-manager-model 创立胜利后,咱们手动配置它的 packaging 属性值为 jar。

5. 按照第 4 步,再别离创立 javaboy-manager-service 以及 javaboy-manager-dao 6. 持续创立 javaboy-manager-web 模块,不同于其余模块,web 模块须要打包成 war。web 模块创立能够参考【第五篇文章】。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 也能拜访到。

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

接下来就能够在不同的模块中写代码,而后进行我的项目部署了。部署形式参考【第五篇文章】

有一个须要留神的中央,在多模块我的项目中,web 我的项目打包须要留神以下问题:

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


微信公众号【程序员黄小斜】作者是前蚂蚁金服 Java 工程师,专一分享 Java 技术干货和求职成长心得,不限于 BAT 面试,算法、计算机根底、数据库、分布式、spring 全家桶、微服务、高并发、JVM、Docker 容器,ELK、大数据等。关注后回复【book】支付精选 20 本 Java 面试必备精品电子书。

退出移动版