Maven最全知识

github地址
https://github.com/a18792721831/studyMaven.git
文章列表:
Maven最全知识
[INFO] Generating project in Batch mode
Maven项目的目录结构
Maven仓库解析
Maven pom.xml解析
MVN命令与生命周期
Maven私有仓库的搭建和使用
Maven依赖

1. Maven介绍

1.1 什么是Maven

Maven:一个用于自动化构建项目和管理项目依赖的工具。

image-20201017125256152

来源于百度百科

自动化构建项目:按照企业中主流的项目模板,创建完善的项目结构。

管理项目依赖:配置式添加和管理,自动下载和导入。

正常情况下,我们创建一个项目,项目中用到的jar包都需要自己下载下来,然后手动导入到工程中,然后在工程中才能使用这些jar包,从而避免我们自己重复写轮子。

spring–hello~!(如何搭建一个spring项目)

springMVC-hello

扫描二维码关注公众号,回复: 12390671 查看本文章

这些都需要手动导入需要jar包,但是这样就存在一些问题:

  1. 手动下载、管理、导入依赖
  2. 代码或者说项目与IDE与开发者的环境有相关性
  3. 操作繁琐,不易操作

所以,一个自动化构建项目,和管理项目依赖的工具就非常的有必要性。

1.2 为什么要使用Maven

在1.1中,我们知道了,有一个自动构建,自动处理依赖的工具,是非常有用的。那么,自动化构建,自动处理依赖的工具,也有很多,不仅仅只有Maven,还有Gradle等等。可能还有一些其他的,只不过可能比较少接触到。

目前为止,我目前接触到的自动化构建和管理依赖的工具,有Maven和Gradle。

如果是简单的自动化构建项目,和管理依赖,这两个其实都非常的简单,没有什么难度。

只是,在更高深的地方有一些差异:

Maven Gradle
xml Groovy
插件多 可以自己写操作
不灵活 进阶难度高

因为Maven是使用xml的方式进行配置,而Gradle是使用Groovy语言进行配置。所以,Gradle的灵活性上可能不如Maven。

但是,也基于Maven使用xml的方式进行配置,所以 ,学习的难度上要比Gradle更加简单,毕竟想要学习高阶的Gradle,那么Groovy语言是绕不过的门槛。

所以,Gradle高阶的难度比较高。

因为Maven使用xml进行配置,所以,如果想要定制化一些自己的操作,一般是创建自己的插件,然后在项目中使用,而Gradle是使用Groovy语言进行配置,而Groovy语言是一门编程语言,所以一些简单的,小的操作,自定义的操作,完全可以用几行Groovy代码就搞定了。前提是你要会写Groovy的代码。

基于以上种种原因,目前Maven正在逐步走向淘汰,更多的使用Gradle,而Gradle的基本的思想和理念也和Maven相同,甚至Maven项目和Gradle项目可以很轻松的互转。

2. Maven入门

2.1 Maven环境的搭建

第一步:java环境

Maven主要是构建java为主的项目,所以,Maven环境是基于Java环境的,在搭建Maven环境前,首先需要保证自己有一个版本不是非常低的java环境。

我的java环境是jdk8的java环境。保证就Java相关的环境是可用的。

image-20201017131552672

第二步:下载Maven

Maven官网下载Maven.

image-20201017131747515

解压压缩包:

image-20201017131920009

解压后的目录如下

image-20201017131956296

第三步:配置环境变量

Maven有三个大的版本:1,2,3

在1中主要配置MAVVENN_HOME环境变量

在2中主要配置M2_HOME环境变量

在3中主要配置PATH环境变量

当然,你要全部都配置上去,也是没有问题的。

我们拷贝Maven解压文件夹中bin目录的地址,然后在系统的环境变量中增加这个路径(系统的环境变量如何配置请网上查找即可)。
image-20201017132505710

打开命令行,输入mvn命令有反应,那么Maven环境就算配置完成了。

MAVEN_HOME环境变量的值是通过bin目录下mvn程序相对路劲进行查找的。

所以MAVEN_HOME如果想要配置,配置到Maven解压目录即可。

2.2 Maven项目的创建

创建模块

首先打开idea,然后配置idea中的maven。

image-20201017150840705

然后创建项目:

image-20201017150934704

接着配置一些版本信息(创建的项目的版本)

image-20201017151049794

接着展示最终的信息,这个信息主要是用于确认,是否和预期一致。

image-20201017151117878

点击finish后,就开始自动下载数据。需要访问外网(我自己挂着vpn)

image-20201017151240006

等待一会就完成了

image-20201017151314419

Maven已经自动创建相关的目录。

image-20201017151339343

但是这个自动创建的项目,目前已有的依赖非常有限,只有两个:

image-20201017151520985

其中jdk11是project的版本,新创建的moduel是jdk8.

增加依赖

我们需要的依赖肯定不只只是这两个,所以,我们就需要在网上寻找我们需要的依赖。

打开Maven官方搜索网站搜索我们需要的依赖。

搜索servlet-api

image-20201017151930915

找到最新版,然后拷贝Maven版本的依赖

这个网站支持各种各样的自动化构建工具,比如Gradle,Groovy,Scala等等。

image-20201017152014860

然后复制到我们新创建的模块下的pom.xml中的dependencies

image-20201017152309868

拷贝完成后,需要我们指定依赖范围:

image-20201017152648273

报异常是因为本地没有这个版本,还未下载,所以接着点击按钮,刷新依赖

image-20201017152352491

刷新完成后,就不在报异常了

image-20201017152420907

接下来增加jsp的依赖

image-20201017152550261

刷新完成后所有的依赖就全部搞定了。

配置插件

我们虽然将依赖引入了,但是还缺少一些插件。

同样的,在Maven官方插件搜索

image-20201017153118448

但是像其中一些常用的,默认就已经加入了

image-20201017153200112

我们主要是想增加tomcat的插件

image-20201017153240677

点击tomcat后,会展示支持的版本

image-20201017153324155

我们选择最新的版本

点进入后会看到这个版本的tomcat插件使用的一些要求,以及相关的插件配置代码

image-20201017153422950

我们使用tomcat7就够了

image-20201017153538601

然后刷新

image-20201017154356745

运行项目

第一种,使用命令运行

创建Maven命令的方式运行:

image-20201017154613009

点击运行或者调试

image-20201017154711382

第一次运行会下载一些相关的数据,下载完成后,就会将容器启动成功

接着访问url,验证是否启动成功

image-20201017154858290

浏览器访问成功

image-20201017154933362

这个Hello World就是项目中index.jsp中的内容

image-20201017155007432

第二次运行就不在重新下载数据了

image-20201017155037277

第二种,使用本地tomcat运行

image-20201017155631967

image-20201017155657771

image-20201017155721334

image-20201017155731171

image-20201017155746867

image-20201017155912484

运行或者调试

image-20201017155931972

image-20201017160002003

image-20201017160008552

自动打开。

3. 目录结构分析

3.1 Maven工作原理

Maven主要的工作原理

image-20201017162238962

Maven说白了就是一个下载工具。

3.2 Maven目录结构

Maven项目的文件结构

image-20201017162309444

  • bin:存放二进制程序

    image-20201017162703129

  • boot:Maven的类加载器,存储Maven自己的jar包

    image-20201017162715223

  • conf:里面主要是settings.xml存放位置

    image-20201017162730132

  • lib:存放Maven的类库文件

    image-20201017162745914

  • usrlibs:自定义仓库的位置

  • LICENSE:声明文件

  • NOTICE:版本信息

  • README.txt:说明文件

3.3 Maven项目的目录结构

image-20201017162847837

比如

image-20201017163020432

  • src:源码,静态文件等等
  • target:编译打包后的文件
  • pom.xml:依赖对象模型

pom:

project object model 项目对象模型

package object management 依赖包对象管理器

项目目录结构,只是约定大于规范的结构。

有些目录可以缺少。

4. 仓库解析

仓库分类

远程仓库、中央仓库,镜像仓库。

本地仓库:默认:C:/User/用户名/.m2/repository/

Maven仓库私服:Neuex…

这些仓库的结构,如图所示

image-20201017163700544

远程仓库配置

image-20201017163842351

	 <mirror>
		<id>aliyunMaven</id>
		<name>aliyun Maven</name>
		<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
		<mirrorOf>central</mirrorOf>
	 </mirror>

本地仓库配置

image-20201017164506603

刷新项目,重新下载依赖,此时,依赖的包已经被下载到指定的本地仓库了

image-20201017164556215

image-20201017164720513

5. pom.xml解析

对于Maven来说,核心的配置只有两个,分别是setting.xmlpom.xml

5.1 setting.xml

在Maven的config目录下,有一Maven自己的setting.xml文件。

image-20201026194535681

相关的配置说明如下:

image-20201026194927929

在配置文件中也有说明

image-20201026195415444

当然,Maven和Gradle类似,在跟项目中可以配置整个跟项目的配置,跟项目的配置,全部的子项目共享。

所以,在Gradle中有setting.gradlesetting.gradle在跟项目的路径下。

相对应的,在Maven中也有setting.xmlsetting.xml也在跟项目的路径下。

子项目共享跟项目的配置。

5.2 pom.xml

在项目中,有项目自己的配置。

比如在Gradle中是build.gradle,在Maven中就是build.gradle了。

到目前为止,我们现在有三个配置文件:Maven的配置,跟项目的配置,子项目的配置。

那么,这三个项目的优先级是怎么样的呢?

pom.xml > settings.xml(project) > settings.xml(maven)

也就是说,子项目中配置的是优先级最高的,接下来是跟项目的配置,最后是Maven的配置。

  • 项目基础信息配置
  • 项目构建环境配置
  • 项目仓库管理配置
  • 项目依赖管理配置
  • 项目报表信息配置
  • 项目部署分发配置
<?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">
  <!-- 1.项目基本信息配置-->
  <!--父项目的坐标,如果子项目中没有配置相关的信息,那么使用父项目中的配置。
  坐标包括:
  groupID,artifactID和version。-->
  <parent>
    <!--被继承的父项目标识符-->
    <artifactId>studyMaven</artifactId>
    <!--被继承的父项目的全球唯一标识符-->
    <groupId>org.study</groupId>
    <!--被继承的父项目的版本-->
    <version>1.0-SNAPSHOT</version>
    <!--被继承的父项目的pom.xml文件的相对路径。相对路径允许选择一个不同的路劲。默认是../pom.xml。-->
    <relativePath>../pom.xml</relativePath>
  </parent>
  <!--生命项目描述符尊新哪一个POM模型版本。模型本身的版本很少改变,但是依然是必不可少的。-->
  <modelVersion>4.0.0</modelVersion>
  <!--子项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成。-->
  <groupId>org.study</groupId>
  <!--构件的标识符,它和groupId一起唯一标识一个构件。换句话说,同一个groupId下的artifactId不可重复.-->
  <!--构件是项目生产的或者使用的一个东西,Maven为项目产生的构件包括:jar,war,源码和二进制。-->
  <artifactId>study-helloMaven</artifactId>
  <!--子项目的版本.-->
  <version>1.0-SNAPSHOT</version>
  <!--项目产生的构件类型。-->
  <packaging>war</packaging>
  <!--项目的名称,Maven用于生成文档.-->
  <name>study-helloMaven Maven Webapp</name>
  <!-- 项目的主页URL,Maven用于生成文档。-->
  <url>http://www.example.com</url>
  <!--项目的详细描述,Maven产生文档使用。
  可以使用HTML格式描述,类似javaDoc.-->
  <description>study maven project.</description>
  <!--项目创建的年份-->
  <inceptionYear>2020</inceptionYear>
  <!--项目先关的邮件列表信息-->
  <mailingLists>
    <!--项目相关的所有的邮件列表,自动产生的网站引用这些信息.-->
    <mailingList>
      <!--邮件的名称-->
      <name>study</name>
      <!--发送邮件的地址或者链接,如果是邮件地址,创建文档时,mailto:链接会被自动创建-->
      <post>[email protected]</post>
      <!--订阅邮件的地址或者链接-->
      <subscribe>[email protected]</subscribe>
      <!--取消订阅邮件的地址或者链接-->
      <unsubscribe>[email protected]</unsubscribe>
      <!--浏览邮件信息的URL-->
      <archive>http://localhost:8080/</archive>
    </mailingList>
  </mailingLists>
  <!--项目开发者列表-->
  <developers>
    <!--某个项目开发者的信息-->
    <developer>
      <!--SCM李项目开发者的唯一标识-->
      <id>xx</id>
      <!--项目开发者的全名-->
      <name>zz</name>
      <!--项目开发者的email-->
      <email>[email protected]</email>
      <!--项目开发者的主页-->
      <url>http://xxx.com</url>
      <!--项目开发者在项目中扮演的角色-->
      <roles>
        <role>user1</role>
        <role>manage1</role>
      </roles>
      <!--项目开发者所属组织-->
      <organization>study</organization>
      <!--项目开发者所属组织的URL-->
      <organizationUrl>http://study.com</organizationUrl>
      <!--项目开发者属性,即时信息处理等等-->
      <properties>
        <dept>XX</dept>
      </properties>
      <!--项目开发者所在的时区-->
      <timezone>+8</timezone>
    </developer>
  </developers>
  <!--项目的其他贡献者列表-->
  <contributors>
    <!--项目的其他贡献者-->
    <contributor>
      <name>zz</name>
      <email>[email protected]</email>
      <url>http://www.baidu.com</url>
      <organization>xx</organization>
      <organizationUrl>http://xx.com</organizationUrl>
      <roles>
        <role>xx</role>
      </roles>
      <properties>
        <zz>x</zz>
      </properties>
      <timezone>7</timezone>
    </contributor>
  </contributors>
  <!--项目所以有的License列表.-->
  <licenses>
    <!--项目的license,用于生成项目的web站点的license页面,一些报表等也会用到-->
    <license>
      <!--license用于法律上的名称-->
      <name>Apache2</name>
      <!--官方的license正文页面的URL-->
      <url>http://www.baidu.com</url>
      <!--项目分发的主要方式:repo,可以从Maven库下载;manual,用户必须手动下载和安装依赖-->
      <distribution>repo</distribution>
      <!--关于license的补充信息-->
      <comments>this is the comments</comments>
    </license>
  </licenses>
  <!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其他插件使用-->
  <scm>
    <!--SCM的URL,描述了版本库和如何连接到版本库。-->
    <connection>scm:svn:http://svn.xx.com/maven/xxxxx</connection>
    <!--给开发者使用,类似conntecion元素,连接不仅仅只读-->
    <developerConnection>scm:svn:http://svn.xxx.com/xxxx</developerConnection>
    <!--当前代码的标签,开发阶段默认为HEAD-->
    <tag>1</tag>
    <!--指向项目的可浏览SCM库的URL.-->
    <url>http://svn.xxxx.com</url>
  </scm>
  <!--描述项目所属组织的各种属性,Maven产生文档使用-->
  <organization>
    <!--组织的全名-->
    <name>hello</name>
    <!--组织的主页-->
    <url>http://wwww.hello.com</url>
  </organization>

  <!-- 2.项目构建环境配置-->
  <!--描述了项目构建环境中的前提条件-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
  <!--项目问题管理系统-->
  <issueManagement>
    <!--问题管理系统的名字-->
    <system>jira</system>
    <!--问题管理系统的url-->
    <url>http://jira.xxxx.com</url>
  </issueManagement>
  <!--项目持续集成信息-->
  <ciManagement>
    <!--持续集成系统的名字-->
    <system>jenkins</system>
    <!--持续集成系统的地址-->
    <url>http://jenkins.xx.com</url>
    <!--构建完成时,需要通知的开发者,或者用户拒的配置:包括成功,失败,异常,警告等)-->
    <notifiers>
      <!--配置一个通知-->
      <notifier>
        <!--发布通知的方式-->
        <type>mail</type>
        <!--发生错误时是否通知-->
        <sendOnError>true</sendOnError>
        <!--构建失败时是否通知-->
        <sendOnFailure>true</sendOnFailure>
        <!--构建成功时是否通知-->
        <sendOnSuccess>true</sendOnSuccess>
        <!--构建发生警告时是否通知-->
        <sendOnWarning>true</sendOnWarning>
        <!--通知哪些人-->
        <address>[email protected]</address>
        <!--扩展配置-->
        <configuration/>
      </notifier>
    </notifiers>
  </ciManagement>
  <!-- 模块(子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路劲.-->
  <modules>
    <!--模块的名字-->
    <!--
    <module>helloMaven</module>
    -->
  </modules>
  <!--项目的依赖-->
  <dependencies>
    <!--一个依赖-->
    <dependency>
      <!--被依赖的包的标识符-->
      <groupId>junit</groupId>
      <!--被依赖的包的唯一标识符-->
      <artifactId>junit</artifactId>
      <!--被依赖的包的版本-->
      <version>4.11</version>
      <!--被依赖的包的作用范围(子项目,全部项目,测试,系统。。。)-->
      <scope>test</scope>
      <!--依赖的方式-->
      <type>jar</type>
      <!--被依赖的jar包的编译方式-->
<!--      <classifier>jdk11</classifier>-->
      <!--操作系统的路径-->
<!--      <systemPath></systemPath>-->
      <!--计算依赖时,排除的依赖列表-->
      <exclusions>
<!--        <exclusion>-->
<!--          <groupId>org.apache</groupId>-->
<!--          <artifactId>apache</artifactId>-->
<!--        </exclusion>-->
      </exclusions>
      <!--依赖是否是可选依赖-->
      <optional>false</optional>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>1.23</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <!--构建项目需要得到信息-->
  <build>
    <!--项目源码目录,相对路径,相对于pom.xml-->
    <sourceDirectory>src</sourceDirectory>
    <!--项目脚本目录。脚本不会参与编译以,但是当构建完成后,会被拷贝到输出目录。因为脚本是解释执行的,不是编译执行的。-->
    <scriptSourceDirectory>src/main/resources</scriptSourceDirectory>
    <!--单元测试的源码目录-->
    <testSourceDirectory>src/test</testSourceDirectory>
    <!--编译过的应用程序的class文件存放位置-->
    <outputDirectory>.out</outputDirectory>
    <!--单元测试编译后的class文件存放位置-->
    <testOutputDirectory>.out</testOutputDirectory>
    <!--扩展的构建-->
    <extensions>
      <!--扩展的构建-->
      <!--
      <extension>
        <!-扩展的构建的标识符
        <groupId>xx</groupId>
        <!-扩展的构建的唯一符
        <artifactId>xzx</artifactId>
        <!-扩展构建的版本
        <version>1</version>
      </extension>
      -->
    </extensions>
    <!--项目没有规定目标时的默认值-->
    <defaultGoal>succ</defaultGoal>
    <!--项目的资源信息-->
    <resources>
      <!--一类资源-->
      <resource>
        <!--资源文件的目标路径-->
        <targetPath>.target</targetPath>
        <!--是否启用参数-->
        <filtering>false</filtering>
        <!--资源存放的目录,相对pom.xml的路劲-->
        <directory>src/main/resources</directory>
        <!--包含的模式列表-->
        <includes>
          <include>**/*.yaml</include>
        </includes>
        <!--排除的模式列表-->
        <excludes>
          <exclude>**/*.log</exclude>
        </excludes>
      </resource>
    </resources>
    <!--单元测试的资源信息-->
    <testResources>
      <testResource>
        <targetPath>.target</targetPath>
        <filtering>false</filtering>
        <directory>src/test/resources</directory>
        <includes>
          <include>**/*.yaml</include>
        </includes>
        <excludes>
          <exclude>**/*.log</exclude>
        </excludes>
      </testResource>
    </testResources>
    <!--构建产物最终的名字-->
    <finalName>study-helloMaven</finalName>
    <!--项目可以引用的默认插件信息。插件配置项直到被引用,才会被解析或绑定到生命周期。-->
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <!--插件列表-->
      <plugins>
        <!--插件信息-->
        <plugin>
          <!--插件在仓库中的groupId-->
          <groupId>org.apache.tomcat.maven</groupId>
          <!--插件在仓库中的唯一符-->
          <artifactId>tomcat7-maven-plugin</artifactId>
          <!--插件在仓库中的版本-->
          <version>2.2</version>
          <!--是否下载Maven扩展,影响性能-->
          <extensions>false</extensions>
          <!--构建生命周期中执行一组目标配置,可以有多组目标配置,每组目标配置可能不同-->
          <executions>
            <!--一组目标配置-->
            <execution>
              <!--目标配置的标识-->
              <id>1</id>
              <!--绑定构建生命周期阶段-->
              <phase>clean</phase>
              <!--配置的目标值-->
              <goals>
                <goal>run</goal>
              </goals>
              <!--配置传播范围-->
              <inherited>false</inherited>
              <!--DOM对象的配置-->
              <configuration>
                <address>127.0.0.1</address>
                <port>8080</port>
              </configuration>
            </execution>
          </executions>
          <!--项目引入插件需要引入的额外的依赖-->
          <dependencies>
            <dependency>
              <groupId>org.apache</groupId>
              <artifactId>apache</artifactId>
              <version>21</version>
              <scope>provided</scope>
            </dependency>
          </dependencies>
        </plugin>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
  <!--配置的环境列表-->
  <profiles>
    <!--一个环境-->
    <profile>
      <!--环境id-->
      <id>dev</id>
      <!--profile的条件,是否使用这个环境的判断条件.-->
      <activation>
        <!--环境是否是默认环境-->
        <activeByDefault>false</activeByDefault>
        <!--条件-->
        <jdk>jdk11</jdk>
        <!--环境的os条件-->
        <os>
          <!--os的名字-->
          <name>Linux</name>
          <!--os的组-->
          <family>root</family>
          <!--os的体系-->
          <arch>x64</arch>
          <!--os的版本-->
          <version>7</version>
        </os>
        <!--环境的file条件-->
        <file>
          <!--如果存在文件-->
          <exists>/usr/local/xx.l</exists>
          <!--如果不存在文件-->
          <missing>/usr/local/yy.l</missing>
        </file>
        <!--jdk和os和file任一满足就会使用环境-->
        <!--环境值-->
        <property>
          <!--变量名-->
          <name>x</name>
          <!--变量值-->
          <value>y</value>
        </property>
      </activation>
      <build>
      </build>
    </profile>
  </profiles>
  <!-- 3.项目仓库管理配置-->
  <!--发现依赖和扩展的远程仓库列表-->
  <repositories>
    <!--远程仓库-->
    <repository>
      <!--远程仓库的标识-->
      <id>r1</id>
      <!--远程仓库的名字-->
      <name>release</name>
      <!--远程仓库的url-->
      <url>http://sss.com</url>
      <!--仓库的布局类型-->
      <layout>default</layout>
      <!--如何处理远程仓库发布版本的下载-->
      <releases>
        <!--是否下载该仓库的发布版本-->
        <enabled>false</enabled>
        <!--更新频率-->
        <updatePolicy>never</updatePolicy>
        <!--Maven验证构件失败时,如何处理(ignore:忽略;fail:失败;warn:警告;)-->
        <checksumPolicy>warn</checksumPolicy>
      </releases>
      <!--如何处理远程仓库快照版本的下载-->
      <snapshots>
        <!--是否下载快照版本-->
        <enabled>false</enabled>
        <!--更新频率-->
        <updatePolicy>never</updatePolicy>
        <!--处理方式-->
        <checksumPolicy>warn</checksumPolicy>
      </snapshots>
    </repository>
  </repositories>
  <!--插件的远程仓库列表,插件用于构建和报表-->
  <pluginRepositories>
    <pluginRepository>
      <id>r2</id>
      <name>xx</name>
      <url>http://cc.xom</url>
      <layout>default</layout>
      <releases>
        <enabled>false</enabled>
        <updatePolicy>never</updatePolicy>
        <checksumPolicy>warn</checksumPolicy>
      </releases>
      <snapshots>
        <enabled>false</enabled>
        <updatePolicy>never</updatePolicy>
        <checksumPolicy>warn</checksumPolicy>
      </snapshots>
    </pluginRepository>
  </pluginRepositories>
  <!--5.项目报表信息配置-->
  <!--描述产生报表的规范,执行"mvn site",报表就会运行.-->
  <reporting>
    <!--true:不包括默认报表-->
    <excludeDefaults>true</excludeDefaults>
    <!--产生的报表存放在哪里-->
    <outputDirectory>.site</outputDirectory>
    <!--报表插件和相关的配置-->
    <plugins>
      <!--报表插件-->
      <plugin>
        <!--报表插件的groupId-->
        <groupId>org.apache.maven.plugins</groupId>
        <!--报表插件的唯一符-->
        <artifactId>maven-site-plugin</artifactId>
        <!--报表插件的版本-->
        <version>3.3</version>
        <!--是否传播到子项目-->
        <inherited>false</inherited>
        <!--配置项-->
        <configuration/>
        <!--报表的多重规范-->
        <reportSets>
          <!--一个规范-->
          <reportSet>
            <!--id-->
            <id/>
            <!--产生报表时的配置-->
            <configuration/>
            <!--配置是否传播到子项目-->
            <inherited/>
            <!--这个规范用到了哪些报表-->
            <reports/>
          </reportSet>
        </reportSets>
      </plugin>
    </plugins>
  </reporting>
  <!--6.项目分发配置-->
  <!--项目分发配置,就是执行mvn deploy后将要执行的操作-->
  <distributionManagement>
    <!--部署项目产生的构建发布到远程仓库需要的信息-->
    <repository>
      <!--分配给快照的版本号(唯一)-->
      <uniqueVersion>false</uniqueVersion>
      <id>1</id>
      <name>xx</name>
      <url>ftp://xx.com</url>
      <layout>default</layout>
    </repository>
    <!--构建的快照部署到哪里?默认部署到repository配置的仓库,或者默认仓库-->
    <snapshotRepository>
      <uniqueVersion>false</uniqueVersion>
      <id>1</id>
      <name>xx</name>
      <url>ftp://ss.com</url>
      <layout>default</layout>
    </snapshotRepository>
    <!--部署项目的网站需要的信息-->
    <site>
      <!--部署位置的唯一标识符-->
      <id>xxx</id>
      <!--部署位置的名称-->
      <name>xxxx</name>
      <!--部署位置的URL-->
      <url>scp://svn.baidu.com</url>
    </site>
    <!--项目下载页面的URL,该元素的原因是:帮助定位不在仓库里的构件-->
    <downloadUrl>http://www.baidu.com</downloadUrl>
    <!--如果构件有了新的groupId,artifactId,那么在这里应该列出来-->
    <relocation>
      <groupId>xxxx</groupId>
      <artifactId>xxxx</artifactId>
      <version>xxx</version>
      <message>xxxx</message>
    </relocation>
    <!--是否有效-->
    <status>none</status>
  </distributionManagement>
</project>

6. GAV软件定位坐标

GAV是指(GroupId,ArtifactId,Version)首字母的简写。

  • GroupId:项目id,是区分当前项目和其他项目的唯一标志.
  • ArtifactId:组件id,在当前项目内,是区分当前组件和其他组件的唯一标识.
  • Version:版本号,对于同一个组件,有着不同的版本,这是区分一个组件不同版本的唯一标识。

举例:

image-20201028192944793

这个依赖表示:

org.apache中的logging.log4j项目,这个项目中的log4j组件,版本是2.13.3版本。

版本号的意义

软件名称.主版本号.小版本号.阶段版本号.字母版本号

  • 主版本号:软件重大功能新增和修改
  • 小版本号:小功能的新增和修改
  • 阶段版本号:bug修复
  • 字母版本号:里程碑变更(alpha,正式开启开发,内测;beta,公测版本;rc,候选;stable,正在发型;release,r,ra发型版本;final,最终版本)

7. MVN命令与生命周期

7.1 MVN命令

image-20201028194458234

  1. mvn --version查看maven的版本

    image-20201028195240682

  2. mvn clean清楚生成的class文件等,主要是清理target中的数据

    image-20201028195705509

  3. mvn compile编译源码,与mvn clean刚好相反

    image-20201028195813172

  4. mvn package打包,将class,资源文件打入jar包或者war包

    image-20201028195839168

  5. mvn tomcat:run运行tomcat容器

    image-20201028195923683

  6. mvn test执行test单元测试,生成测试报告

    image-20201028195950386

  7. mvn site生成报表

    image-20201028200057145

  8. mvn dependency:tree分析依赖树,在用于解决依赖冲突时,非常有效

    image-20201028200134852

  9. mvn install下载依赖,更新依赖

    image-20201028200156744

  10. mvn deploy发布打包后的文件

    image-20201028200217147

不过,更多的是使用ide里面的图形化操作

image-20201028200257941

7.2 Maven生命周期

生命周期:描述项目构建过程。也是预定义项目执行过程。降低项目管理的难度 。

  1. clean:项目构建之前清理
  2. default:项目编译和打包,安装,分发,部署。。
  3. site:项目报告,站点,发布

image-20201028200622638

8. Maven项目构建

8.1 纯手工构建

这是Maven项目的结构

image-20201028201003305

在ide中创建一个空的java工程,然后手工创建Maven项目的其他结构:

image-20201028201344807

image-20201028201559069

接着填充pom.xml

image-20201028201927550

此时在命令行中就可以运行Maven的命令了:

image-20201028202009868

或者像这样,一次性执行多个独立的命令

image-20201028202055913

但是此时ide还是不识别pom.xml文件:

image-20201028202117958

需要手动导入

image-20201028202205050

导入完成后,ide就会识别这些文件了

image-20201028202242543

8.2 模板构建

模板构建就更简单了,直接在创建模块或者项目时,选择maven就好了。

这些文件结构,相关的pom.xml文件的文件头,以及pom.xml文件的导入等等,都会一次性完成。

image-20201028202414781

而且连依赖都可以直接选择好。

8.3 命令构建

image-20201028202749739

9. 依赖范围

什么是依赖范围

依赖范围:依赖的jar包,在Maven的生命周期生效的范围。

有哪些依赖范围

image-20201029192102582

作用范围主要包含这几个:

  • compile:全部周期
  • provided:编译和运行
  • runtime:运行和打包
  • test:测试
  • system:与provided配合使用

image-20201029192323364

为什么设置依赖范围

默认的依赖范围是全局的,也就是如果不写,就默认在全部的生命周期有效。

那么,这样不是很好吗?全部都能用,这样不是更方便吗?

不是,举个最常见的例子:

我们的spring mvc项目中需要指定servlet,在开发的时候,我们用到的是jar包的servlet。在开发完成后,需要打包成jar包或者war包,然后部署到tomcat容器或者Jboss容器中,进行部署。但是,Tomcat或者Jboss的就已经包含了servlet了,我们的jar包或者war也有servlet的话,不就出现冲突了吗。

有了依赖范围,我就可以设置,让打包的时候,不要将servlet打入发布包,这样就不会存在问题了。

10. 项目继承的依赖

父子项目:依赖的继承关系只会发生在父子项目之间。

父子项目:最顶层的项目是父项目,父项目下面的项目就是子项目。

子项目默认拥有父项目的依赖,如果子项目也做了依赖的配置,那么以子项目的为准。

父子项目关系是由pom.xml中的parent标签说明。

image-20201029194819188

有了父子项目的关系后,子项目就可以使用父项目的变量,配置,依赖等等。

同时在ide中也会标识出来。

image-20201029195102935

注意:父项目的打包方式必须是pom方式。

11. 项目聚合的依赖

在开发中有一个思想:尽可能使用聚合,而不是继承。

项目依赖的继承,要求项目之间必须有父子关系,才能进行继承。

如果是祖孙项目,就不能继承。

相比来说,聚合关系比依赖关系更加灵活。

聚合关系的设置:是通过modules标签设置的。

image-20201029195916363

我们在聚合的父项目上设置了servlet依赖

image-20201029195944818

但是在子项目上没有设置servlet依赖:

image-20201029200015806

但是子项目依然可以使用servlet依赖中的类
image-20201029200043604

聚合与继承的区别:

继承是子项目维护关系,子项目通过增加parent标签维护。

聚合是被聚合项目维护关系,子项目不需要做任何操作。

如果顶层项目下有许多的下级项目,这些下级项目都需要依赖一个jar包。

而且决定将jar包放到了顶层项目中。

如果使用继承关系,需要在全部的下级项目中增加标签。

如果使用聚合关系,只需要在顶层项目中增加全部的下级项目。

从这方面来说,可能聚合比依赖更加的快捷,方便。

聚合和继承可以同时使用。

12. 项目常用插件

插件是一些普通的Maven命令的增强。

插件按照用途有生命周期插件,有容器插件,有依赖插件,部署插件,。。。

常用的有:resource,source,clean ,compile,tomcat,denpendenc,jar,build…

插件可以去Maven官网检索。

比如依赖相关的:

image-20201029200959000

通过点击useage查看如何配置:

image-20201029201051599

然后将给出的代码拷贝到自己的pom.xml中对应的位置即可。

image-20201029201220486

使用

image-20201029203445643

不过现在IDE很强大,基本上不再这么使用了。依赖分析,IDE比命令行更加直观。

image-20201029203948144

13. 私有仓库

私有服务器

image-20201031131350577

一方面可以加快依赖加载速度,另一方面,可以解决一些内部依赖的安全性。

搭建私有服务器有哪些解决方案:

  • Apache Archiva
  • JFrog Artifactory
  • Sonatype Nexus

私有服务器的架设

下载nexus.

Nexus官网文档下载与配置。

不过,得益于现在docker的发展,现在基本上常见的应用,都有对应的docker镜像。

所以,我们就不在重新搭建Nexus,而是直接启动最新的镜像。

打开docker-hub官网然后搜索nexus的镜像:

image-20201031132743851

各种启动的场景,都给出了相关的启动的命令和相关的示例配置

image-20201031132927536

所以,我们直接在服务器上启动一个容器:

image-20201031133251654

这是两个命令,在第一个命令创建成功的基础上执行第二个命令。

第一个命令将在容器内创建一个文件夹,地址在根目录下。

第二个命令将宿主机的data文件夹挂载到容器内,我们刚刚创建的容器内的文件夹内。

结果报错了,查看日志,发现我们参数传递错误:

image-20201031133926332

修改命令和参数,重新启动

image-20201031134428275

  1. 表示创建了一个docker管理的存储
  2. 在容器内使用刚刚创建的存储
  3. 刚刚创建的存储,对应容器内的目录,在宿主机上存储在/var/lib/docker/volumes

尝试访问:

image-20201031134135747

登录

image-20201031134151502

image-20201031134206697

我们使用自动生成的密码登录

image-20201031134810470

ok ,登录成功

image-20201031134857564

image-20201031134955370

私有服务器配置使用

仓库分为三种:proxy,group,hosted.

proxy代理仓库,group分组管理仓库,hosted本地发布仓库。

releases稳定版本发布

snapshots快照版本发布

我们创建一个仓库

BU26tP.gif

然后选择maven2类型的仓库proxy类型的

image-20201031140332544

我们选择使用用户名密码访问验证就行了,是一个代理仓库,目标是阿里云的仓库。

image-20201031140431175

其他两种仓库的创建方式类似。

image-20201031140653448

然后获取仓库的url地址,就可以使用了。

image-20201031142323987

在代码中指定依赖仓库

image-20201031142609038

配置发布仓库

image-20201031144239472

增加了依赖后,刷新maven,然后我们的私服就会从阿里云的仓库同步我们的依赖

image-20201031143251803

当然,发布我们自己的依赖,也是可以的。

发布之前,需要配置用户名和密码

image-20201031144037111

要注意,这里面的server的id需要和配置的发布仓库Id保持一致。

发布仓库和验证信息是通过id进行匹配的。

然后发布

image-20201031144310389

通过浏览器也能发现确实上传了

image-20201031144341157

但是却只是上传到了快照仓库,却没有上传到稳定仓库。

想上传到稳定版本,也非常的简单,只需要将我们的版本号中的快照修改为稳定,即可

image-20201031144620159

当我们的版本号从快照修改为稳定后,发布就会发布到稳定仓库中

image-20201031144659024

image-20201031144714974

14. 依赖冲突

14.1 项目依赖的直接冲突

如果我们的项目中依赖了两个不同的依赖,但是这两个依赖都依赖其他的依赖,而且这两个依赖的C,存在版本冲突

image-20201031145616530

这样,在项目就需要两个版本的相同的依赖

我们依赖这样两个依赖

image-20201031150238802

然后分析依赖,就会发现存在依赖冲突

image-20201031150302705

就会发现1.1和1.1.1存在版本冲突。

poi依赖的是1.1版本

beanutils-core依赖1.1.1版本

一般情况下,依赖可以向后兼容,所以我们指定最新的版本就可以了。

所以,需要排除低版本的依赖。

image-20201031150730278

此时就没有了冲突了

image-20201031150752806

14.2 项目依赖的传递冲突

我们的项目依赖了A,但是A依赖了B和C,项目本身不依赖C

image-20201031145831842

这样就存在了依赖冲突

我们首先创建A,B,C三个模块

image-20201031151232284

然后先打包C

image-20201031151320501

并且上传到私服中

image-20201031151347244

A,B也打包上传。

不同的是A依赖了B,C

image-20201031151554900

然后在D项目中依赖A

image-20201031151719475

分析依赖树

image-20201031151743864

我们排除依赖C

image-20201031151910114

然后分析依赖树

image-20201031151927848

此时在D项目中,就不会依赖C项目了。

15. 总结

到此为止,我们主要学习了Maven基础,Maven配置,Maven实战,Maven依赖等内容。

在Maven基础中,主要是Maven环境搭建,Maven目录结构分析,代码结构分析。

在Maven配置中,主要是仓库配置,pom.xml配置,和软件定位坐标。还有Maven命令与生命周期

在Maven实战中,主要是三种创建Maven项目的方式:手动创建,模板创建,和IDE创建。

在Maven依赖中,主要是Maven依赖范围,依赖的继承和聚合,创建私有仓库,最后是解决依赖冲突。

Maven慢慢的被gradle替代,但是Maven的思想和设计,永远不会过时。

猜你喜欢

转载自blog.csdn.net/a18792721831/article/details/109403359
今日推荐