【Maven基础篇】Maven的安装&依赖管理&生命周期

有时候,不是因为你没有能力,也不是因为你缺少勇气,只是因为你付出的努力还太少,所以,成功便不会走向你。而你所需要做的,就是坚定你的梦想,你的目标,你的未来,然后以不达目的誓不罢休的那股劲,去付出你的努力,成功就会慢慢向你靠近。

导读:本篇文章讲解 【Maven基础篇】Maven的安装&依赖管理&生命周期,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、Maven简介

传统项目管理现状:
传统项目管理
基于以上问题,Maven出现了。

Maven介绍

  • Maven的本质是一款工具,做项目管理的工具
  • 将项目开发和管理过程抽象成一个项目对象模型POM,及Project Object Model

Maven做依赖管理的结构

Maven的作用

  • 项目构建:提供标准的、跨平台的自动化项目构建方式
  • 依赖管理:方便快捷管理项目依赖的资源(jar包),避免资源间的版本冲突问题
  • 统一开发结构:提供标准的、统一的项目结构
    项目结构

二、下载与安装

下载

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

安装

解压zip文件(Maven属于绿色版软件,解压即安装)

在这里插入图片描述

打开文件夹后,各目录的解释:

在这里插入图片描述

环境变量的配置

  • 依赖Java,配置JAVA_HOME
  • 设置Maven自身的运行环境,配置MAVEN_HOME
    在这里插入图片描述
    在这里插入图片描述

做完以上,打开cmd窗口,输入mvn,以下即是配置成功
在这里插入图片描述

三、Maven基础概念

仓库

仓库,用于存储各种资源。简单狭义的讲,存jar包的

仓库如上图:

  • 本地仓库,即我本地计算机中保存的jar包。

  • 工作中,需要某jar包,我们可以去远端的某台服务器上去下载,即中央服务器,对应存储jar包的位置,就叫中央仓库,这个仓库是Maven开发团队服务维护的。

  • 但如果每个人都去中央仓库下载,再加上境外、带宽等因素,下载效率必然很低。由此,私服诞生,这是公司自己的仓库,一般为局域网级别。


在这里插入图片描述

  • 本地仓库:即自己电脑上存储资源的仓库,连接远程仓库获取资源。
  • 远程仓库:即非本机电脑上的仓库。分为中央仓库和私服。中央仓库由Maven团队维护,存储所有资源。私服是公司范围内存储资源的仓库,从中央仓库获取资源。

☀☀☀
私服的作用:

  • 保存具有版权的资源,如自主研发或购买的jar。而中央仓库的jar是开源的,不能存储有版权的资源
  • 一定范围内共享资源,仅对内部开放,不对外共享

坐标

在这里插入图片描述

坐标,用来描述仓库中资源的位置,https://repo1.maven.org/maven2/

weizhi
Maven坐标的主要组成:

  • 组织ID
  • 项目ID
  • 版本号

坐标

鉴于Maven坐标的组成方式,这样搜索是不对的,再者,Maven坐标是给Maven工具用的,它会按照我们提供的坐标去查找、下载、使用这个资源。

坐标的获取:

进入https://mvnrepository.com/,搜索关键字,锁定后选择版本号
在这里插入图片描述
复制Maven下的地址即坐标:
在这里插入图片描述

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

仓库配置

  • 本地仓库配置

在cmd窗口执行mvn后,可以看到在C盘下新增了这个目录,即本地仓库的位置
在这里插入图片描述
更改本地仓库的位置,需要修改配置文件,即安装Maven的conf目录下的settings.xml文件

本地仓库

  • 远程仓库的配置

和本地仓库一样,在setting.xml文件中加入以下配置,用阿里云提供的开源仓库代替maven的中央仓库:

<!--配置具体的仓库的下载镜像-->
<mirror>
  <!--此境像的唯一标识符,来区分不同的mirror元素-->
  <id>nexus-aliyun</id>
  <!--对哪种仓库进行镜像,简单的来说就是要代替哪个仓库-->
  <mirrorOf>central<mirrorOf>
  <!--镜像名称-->
  <name>Nexus aliyun</name>
  <!--镜像url-->
  <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

(到此对镜像的理解又加深了,即和镜子对面的本体一样,但又有其自身的灵活性和优势)

添加在这里:
远程仓库配置
到此,关于仓库的配置,从哪儿下载,下载好以后存本地的哪儿,就都写明白了。

全局setting和用户setting

以上的配置即全局setting,定义了当前计算机中Maven的公共配置,而用户setting即针对每个登录用户,可以做自己的个性化配置。

用户setting
在上面用户的maven目录下,和repository同级的地方复制一份setting文件过来,公共配置和全局setting中的不一样时,用户setting覆盖全局setting

四、第一个Maven项目(手工制作)

  • Maven工程目录结构

Maven的工程结构如图:
工程结构

  • 代码准备

照着以上的目录结构,在本地某盘中新建出一个同样结构的目录,在main目录的java文件夹下新建Demo.java:
在这里插入图片描述

package com.llg;

public class Demo{
	public String say(String name){
		System.out.println("hello!" + name);
		return "hello!" + name;
	}
}

同样在test目录下的java文件夹下,写一个DemoTest.java的测试程序:

package com.llg;

import org.junit.Test;
import org.junit.Assert;

public class DemoTest{
	@Test
	public void testSay(){
		Demo d = new Demo();
		String ret = d.say("maven");
		Assert.assertEquals("hello!maven",ret);
	}
}

在src目录下新建pom.xml文件,文件内容如下:
文件内容

  • 手动构建指令

Maven的构建命令使用mvn开头,后面添加功能参数,可以一次执行多个指令,使用空格分隔

  • mvn compile 编译
  • mvn clean 清理编译出来的结果
  • mvn test 测试
  • mvn package 打包
  • mvn install 安装到本地仓库

打开DOS窗口,
cmd
在这里插入图片描述
在cmd窗口输入指令mvn compile



运行结果报这个错误的时候,是maven的setting文件中写的jdk版本的问题,解决参考这篇https://blog.csdn.net/qq_45737419/article/details/106790054

error



编译成功如下图:
success
在这里插入图片描述
cmd窗口执行指令mvn clean,则刚才编译产生的文件夹target就被删除了

mvn clean

执行mvn test,结果中可以看到:执行成功1个,失败0个,跳过0个

test

接下来执行mvn package来进行打包:

在这里插入图片描述
在target目录下,可以看到打包成功的jar包:

在这里插入图片描述
接下来执行mvn install,将上一步打好的jar包安装到我们本地的仓库。

在这里插入图片描述

☀30个常用的Maven指令:
https://zhuanlan.zhihu.com/p/29208926

使用mvn插件创建Maven工程

手动创建Maven项目的时候,按照以上一步步去创建目录,再各种新建文件,流程繁琐。可以使用mvn插件直接创建Maven工程。

对于 Maven 插件而言,为了提高代码的复用性,通常一个 Maven 插件能够实现多个功能,每一个功能都是一个插件目标,即 Maven 插件是插件目标的集合。我们可以把插件理解为一个类,而插件目标是类中的方法,调用插件目标就能实现对应的功能。

指令
在cmd窗口执行以上指令创建项目,对比Java工程和web工程在结构上的区别:

在这里插入图片描述

五、第一个Maven项目(IDEA生成)

在IDEA中创建一个空的工程,取名maven-project:
在这里插入图片描述
接下来配置maven,先选择project的SDK:
在这里插入图片描述
接下来file–setting,搜索maven:
在这里插入图片描述
修改home path和setting文件的路径,点击apply。这里的maven版本选择低一些,比如3.6.1,低版本下载地址https://archive.apache.org/dist/maven/maven-3/
在这里插入图片描述

点击新建模块java001,效果如图:
在这里插入图片描述
修改pom文件的内容,添加依赖junit:
在这里插入图片描述
写java源程序Demo和测试程序DemoTest:

在这里插入图片描述

点击右侧生命周期管理,进行测试、编译等:
在这里插入图片描述
除了右侧,也可在这里配置相关的操作:

在这里插入图片描述
可以看到编译测试等操作均成功运行:
在这里插入图片描述



接下来使用IDEA的模板来快速创建Maven工程:

同样新建一个模块,搜索quick,选择quickstart,点击Next:

在这里插入图片描述
接下来一路next后点击Finish,等待下载完成:

在这里插入图片描述

点击新建目录,创建resources,Make Directory as:
在这里插入图片描述



接下来创建Web项目:

继续点击IDEA右上角快捷创建模块,选择maven,搜索web:
在这里插入图片描述
接下来一路next–finish–OK,然后等待加载:

这里加载可能会卡住或者超级慢,可以考虑这三个解决帖子:
https://blog.csdn.net/xwhokay/article/details/122930149
https://blog.csdn.net/qq_38723677/article/details/124795928
https://blog.csdn.net/Zlucien/article/details/114671636

成功后项目结构如下:
在这里插入图片描述
根据自己的需要再修改一下即可:
在这里插入图片描述



下面是Tomcat插件安装和web工程的启动:

进入maven坐标库,搜索tomcat maven,进入这个:
在这里插入图片描述
进入后选择第一项就是需要的插件:
在这里插入图片描述
选择2.1版本后,复制坐标:
在这里插入图片描述

<!-- https://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
<dependency>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
</dependency>

然后进入pom.xml文件,使用build标签来添加插件:
在这里插入图片描述
这时查看右侧Maven可以看到插件(标红是因为正在下载,稍等刷新)
在这里插入图片描述
双击tomcat7:run,开始运行:
在这里插入图片描述
启动成功:

在这里插入图片描述



到此,整体说明一下pom文件各个参数的含义。pom.xml文件的模板:

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- 模型版本。maven2.0必须是这样写,现在是maven2唯一支持的版本 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.winner.trade,maven会将该项目打成的jar包放本地路径:/com/winner/trade -->
    <groupId>com.winner.trade</groupId>

    <!-- 本项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
    <artifactId>trade-core</artifactId>

    <!-- 本项目目前所处的版本号 -->
    <version>1.0.0-SNAPSHOT</version>

    <!-- 打包的机制,如pom,jar, maven-plugin, ejb, war, ear, rar, par,默认为jar -->
    <packaging>jar</packaging>

    <!-- 帮助定义构件输出的一些附属构件,附属构件与主构件对应,有时候需要加上classifier才能唯一的确定该构件 不能直接定义项目的classifer,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的 -->
    <classifier>...</classifier>

    <!-- 定义本项目的依赖关系 -->
    <dependencies>

        <!-- 每个dependency都对应这一个jar包 -->
        <dependency>

            <!--一般情况下,maven是通过groupId、artifactId、version这三个元素值(俗称坐标)来检索该构件, 然后引入你的工程。如果别人想引用你现在开发的这个项目(前提是已开发完毕并发布到了远程仓库),-->
            <!--就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写入, maven就会把你上传的jar包下载到他的本地 -->
            <groupId>com.winner.trade</groupId>
            <artifactId>trade-test</artifactId>
            <version>1.0.0-SNAPSHOT</version>

            <!-- maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。 -->
            <!--scope包含如下的取值:compile(编译范围)、provided(已提供范围)、runtime(运行时范围)、test(测试范围)、system(系统范围) -->
            <scope>test</scope>

            <!-- 设置指依赖是否可选,默认为false,即子项目默认都继承:为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似  -->
            <optional>false</optional>

            <!-- 屏蔽依赖关系。 比如项目中使用的libA依赖某个库的1.0版,libB依赖某个库的2.0版,现在想统一使用2.0版,就应该屏蔽掉对1.0版的依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>

        </dependency>

    </dependencies>

    <!-- 为pom定义一些常量,在pom中的其它地方可以直接引用 使用方式 如下 :${file.encoding} -->
    <properties>
        <file.encoding>UTF-8</file.encoding>
        <java.source.version>1.5</java.source.version>
        <java.target.version>1.5</java.target.version>
    </properties>

    ...
</project>

<build>  
  
    <!-- 产生的构件的文件名,默认值是${artifactId}-${version}。 -->  
    <finalName>myPorjectName</finalName>  
  
    <!-- 构建产生的所有文件存放的目录,默认为${basedir}/target,即项目根目录下的target -->  
    <directory>${basedir}/target</directory>  
  
    <!--当项目没有规定目标(Maven2叫做阶段(phase))时的默认值, -->  
    <!--必须跟命令行上的参数相同例如jar:jar,或者与某个阶段(phase)相同例如install、compile等 -->  
    <defaultGoal>install</defaultGoal>  
  
    <!--当filtering开关打开时,使用到的过滤器属性文件列表。 -->  
    <!--项目配置信息中诸如${spring.version}之类的占位符会被属性文件中的实际值替换掉 -->  
    <filters>  
        <filter>../filter.properties</filter>  
    </filters>  
  
    <!--项目相关的所有资源路径列表,例如和项目相关的配置文件、属性文件,这些资源被包含在最终的打包文件里。 -->  
    <resources>  
        <resource>  
  
            <!--描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。 -->  
            <!--举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven/messages。 -->  
            <!--然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 -->  
            <targetPath>resources</targetPath>  
  
            <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。 -->  
            <filtering>true</filtering>  
  
            <!--描述存放资源的目录,该路径相对POM路径 -->  
            <directory>src/main/resources</directory>  
  
            <!--包含的模式列表 -->  
            <includes>  
                <include>**/*.properties</include>  
                <include>**/*.xml</include>  
            </includes>  
  
            <!--排除的模式列表 如果<include>与<exclude>划定的范围存在冲突,以<exclude>为准 -->  
            <excludes>  
                <exclude>jdbc.properties</exclude>  
            </excludes>  
  
        </resource>  
    </resources>  
  
    <!--单元测试相关的所有资源路径,配制方法与resources类似 -->  
    <testResources>  
        <testResource>  
            <targetPath />  
            <filtering />  
            <directory />  
            <includes />  
            <excludes />  
        </testResource>  
    </testResources>  
  
    <!--项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。 -->  
    <sourceDirectory>${basedir}\src\main\java</sourceDirectory>  
  
    <!--项目脚本源码目录,该目录和源码目录不同, <!-- 绝大多数情况下,该目录下的内容会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。 -->  
    <scriptSourceDirectory>${basedir}\src\main\scripts  
    </scriptSourceDirectory>  
  
    <!--项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。 -->  
    <testSourceDirectory>${basedir}\src\test\java</testSourceDirectory>  
  
    <!--被编译过的应用程序class文件存放的目录。 -->  
    <outputDirectory>${basedir}\target\classes</outputDirectory>  
  
    <!--被编译过的测试class文件存放的目录。 -->  
    <testOutputDirectory>${basedir}\target\test-classes  
    </testOutputDirectory>  
  
    <!--项目的一系列构建扩展,它们是一系列build过程中要使用的产品,会包含在running bulid‘s classpath里面。 -->  
    <!--他们可以开启extensions,也可以通过提供条件来激活plugins。 -->  
    <!--简单来讲,extensions是在build过程被激活的产品 -->  
    <extensions>  
  
        <!--例如,通常情况下,程序开发完成后部署到线上Linux服务器,可能需要经历打包、 -->  
        <!--将包文件传到服务器、SSH连上服务器、敲命令启动程序等一系列繁琐的步骤。 -->  
        <!--实际上这些步骤都可以通过Maven的一个插件 wagon-maven-plugin 来自动完成 -->  
        <!--下面的扩展插件wagon-ssh用于通过SSH的方式连接远程服务器, -->  
        <!--类似的还有支持ftp方式的wagon-ftp插件 -->  
        <extension>  
            <groupId>org.apache.maven.wagon</groupId>  
            <artifactId>wagon-ssh</artifactId>  
            <version>2.8</version>  
        </extension>  
  
    </extensions>  
  
    <!--使用的插件列表 。 -->  
    <plugins>  
        <plugin>  
            <groupId></groupId>  
            <artifactId>maven-assembly-plugin</artifactId>  
            <version>2.5.5</version>  
  
            <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->  
            <executions>  
                <execution>  
  
                    <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->  
                    <id>assembly</id>  
  
                    <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->  
                    <phase>package</phase>  
  
                    <!--配置的执行目标 -->  
                    <goals>  
                        <goal>single</goal>  
                    </goals>  
  
                    <!--配置是否被传播到子POM -->  
                    <inherited>false</inherited>  
  
                </execution>  
            </executions>  
  
            <!--作为DOM对象的配置,配置项因插件而异 -->  
            <configuration>  
                <finalName>${finalName}</finalName>  
                <appendAssemblyId>false</appendAssemblyId>  
                <descriptor>assembly.xml</descriptor>  
            </configuration>  
  
            <!--是否从该插件下载Maven扩展(例如打包和类型处理器), -->  
            <!--由于性能原因,只有在真需要下载时,该元素才被设置成true。 -->  
            <extensions>false</extensions>  
  
            <!--项目引入插件所需要的额外依赖 -->  
            <dependencies>  
                <dependency>...</dependency>  
            </dependencies>  
  
            <!--任何配置是否被传播到子项目 -->  
            <inherited>true</inherited>  
  
        </plugin>  
    </plugins>  
  
    <!--主要定义插件的共同元素、扩展元素集合,类似于dependencyManagement, -->  
    <!--所有继承于此项目的子项目都能使用。该插件配置项直到被引用时才会被解析或绑定到生命周期。 -->  
    <!--给定插件的任何本地配置都会覆盖这里的配置 -->  
    <pluginManagement>  
        <plugins>...</plugins>  
    </pluginManagement>  
  
</build>




六、依赖管理

依赖配置

依赖配置即当前项目运行所需的jar包,一个项目可以设置多个依赖

<!-- 设置当前项目依赖的所有jar包 -->
    <dependencies>

        <!-- 具体的每个依赖,每个dependency都对应这一个jar包 -->
        <dependency>

            <!--一般情况下,maven是通过groupId、artifactId、version这三个元素值(俗称坐标)来检索该构件, 然后引入你的工程。如果别人想引用你现在开发的这个项目(前提是已开发完毕并发布到了远程仓库),-->
            <!--就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写入, maven就会把你上传的jar包下载到他的本地 -->
            <!--依赖所属的群组id-->
            <groupId>com.winner.trade</groupId>
            <!--依赖所属的项目id-->
            <artifactId>trade-test</artifactId>
            <!--依赖的版本号-->
            <version>1.0.0-SNAPSHOT</version>

            <!-- maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。 -->
            <!--scope包含如下的取值:compile(编译范围)、provided(已提供范围)、runtime(运行时范围)、test(测试范围)、system(系统范围) -->
            <scope>test</scope>

            <!-- 设置指依赖是否可选,默认为false,即子项目默认都继承:为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似  -->
            <optional>false</optional>

            <!-- 屏蔽依赖关系。 比如项目中使用的libA依赖某个库的1.0版,libB依赖某个库的2.0版,现在想统一使用2.0版,就应该屏蔽掉对1.0版的依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>

        </dependency>

    </dependencies>

依赖传递

项目1需要用到项目2,则在pom文件中复制项目2自身的坐标,写到项目1的<dependency>中,则2中依赖的jar包,1也可以用了

在这里插入图片描述
图示:
在这里插入图片描述
依赖传递途中,出现了两个不同版本的同一个jar包,优先级理论如下:
在这里插入图片描述
理解就行,工作时刷新右侧Maven,出来哪个自然就是哪个生效了。

可选依赖(不透明)

即,引用我的人看不到我是否用了这个依赖。不想让别人知道我用过这个资源。

<!-- 设置指依赖是否可选,默认为false,即子项目默认都继承:为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似  -->
<optional>false</optional>

java001引用java002,本来可以看到2中引用了log4j:
在这里插入图片描述
被引用的2不想让别人知道引用了log4j,则加optional:
在这里插入图片描述
总结即:被引用方隐藏自己依赖的部分jar

排除依赖(不需要)

即:主动断开依赖的资源,这时不用写版本,三坐标中的version不用

<exclusions>
   <exclusion>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
   </exclusion>
</exclusions>

引用方001,默认可以看到被引用的002的依赖关系,如log4j:
在这里插入图片描述
接下来引用方001来主动排除002中的依赖:

在这里插入图片描述

可选依赖是控制这个资源会不会被引用方看到,排除依赖是引用方去主动断开这个依赖

依赖范围

依赖的jar默认在任何地方都可以使用,可以通过scope标签来更该其作用范围

在这里插入图片描述
标签内容取值如下表:
在这里插入图片描述
依赖范围具有传递性:
在这里插入图片描述

七、生命周期与插件

生命周期,即人几岁的时候,插件即在几岁的时候干的某件事

构建生命周期

项目构建的整体生命周期如下:
在这里插入图片描述

phase标签中填入以下哪个值,则该值及之前的过程全部执行:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


插件

在这里插入图片描述

使用build标签来添加插件:

在这里插入图片描述
execution标签即执行,phase标签即说明插件在哪个阶段执行,goal标签的取值说明:
在这里插入图片描述
jar 用于将项目的主要源代码捆绑到 jar 存档中。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/146087.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!