完全从零Java自学系列【工具篇】(MAVEN编译工具安装与基础使用&工程管理&依赖管理)

摘要

  MAVEN是一个能够帮助你1、管理依赖库,2、构建代码包的命令行工具。它由管理命令,执行周期(生命周期),依赖仓库三大核心点组成。

基础概念

  版本:如果你学习过GITHUB基础概念与使用,当你在实际开发中运用版本,你是希望保存历史和现今版本的,如果你迭代了一个新的版本但是这个版本的迭代出现了问题,你可以选择回滚以达到上一个完美运行的版本。
  编译:依赖有千万种,但是有些依赖你在正式跑项目时是不需要的。因为它们根本就不可能执行。比如测试用例你只会在开发环境(你自己验证时)使用得到,但是你又不可能每次编译时将他们删除。通过日常的配置加上简单的命令来完成N个依赖的编译和打包处理。排除那些不需要的,打包所有需要的。

生命周期

  所谓的生命周期就是在使用的过程中,在什么时间或阶段干了什么事情。当我们使用eclipse或idea打包一个项目时它们的生命周期(执行过程)是单一的。
  Maven的生命周期(执行过程)包含了:清理(删除本地之前编译的)- 构建(验证,编译,执行测试,打包,发送到仓库)- 部署(基本不用)。并且同一个周期内可以有多个组件依次为了该操作执行。Maven将所有的生命周期都封装为了扩展点,也就是说你完全可以自己实现某个过程中的某个处理。
  在MAVEN中如果你执行了打包命令,那么在MAVEN中实际执行了这些命令的集合。(以下每一个周期你都可以引用多个处理该周期的组件,甚至开发自己的扩展去处理):

  1. clean : 清理,就是删除文件
  2. validate :校验,检查是不是合规的maven项目
  3. compile:编译项目中的代码
  4. test :执行项目中的测试案例(你自己编写用于验证正确性的代码)
  5. package :打成jar或者war包
  6. verify :校验jar或war。
  7. install :安装到本地专门存放包的仓库。
  8. site:生成站点文档
  9. deploy:安装到远程专门存放包的仓库。

以clean为例:MAVEN底层的封装并不是直接执行clean,而是检查你是否有执行clean的组件,没有的话就执行自己开发的组件。请注意MAVEN自带的组件也在它本身的声明周期之外。
在这里插入图片描述

安装

Maven下载链接->MAVEN官网地址

安装前的准备

必须要有JAVA环境。如果还没有安装过可以参考:JAVA环境搭建

windows

下载.zip

在这里插入图片描述

解压后放置任意一个目录,并记录位置。和配置JAVA一样,找到环境变量配置的地方。

  1. 编辑系统变量,变量名称你随意,记住了后面还要用别弄错就行(这里是在网络上的截图,和我示例版本无关,因为使用的是mac所以无法为大家完整演示windows,真实的版本需要按你自己下载的来)在这里插入图片描述
  2. 然后在系统变量中继续寻找PATH变量,找到后;%Maven_Home%\bin;将该内容追加到PATH后,注意;是为了区分多个不同的变量(只可多不可能少也就是说你可以;;;;;;;;;;;;;%Maven_Home%\bin;这样都行)。
  3. 确认后在命令行输入 mvn -versionmvn -v校验。

mac

下载.tar.gz
在这里插入图片描述
初学者还是建议不使用Homebrew等工具来安装它。你需要足够了解它的内容,因为该工具(或该类)会一直伴随着你。解压后放置到资源库。
在这里插入图片描述

  1. 如果你还记得安装java环境时的 ~/.zshrc 或者不记得,在~/目录下新建或修改zshrc就可以。可以参考zshrc文件类型的描述,以及如何在命令行新建文件
  2. 我的命令执行过程
apple@apples-MacBook-Pro ~ % vim ~/.zshrc
apple@apples-MacBook-Pro ~ % source ~/.zshrc 
apple@apples-MacBook-Pro ~ % mvn -version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /Library/apache-maven-3.9.6
Java version: 1.8.0_361, vendor: Oracle Corporation, runtime: >/Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "12.6.3", arch: "x86_64", family: "mac"
apple@apples-MacBook-Pro ~ % 
  1. ~/.zshrc文件中的内容:
export MAVEN_HOME=/Library/apache-maven-3.9.6
export PATH=$MAVEN_HOME/bin:$PATH
  1. source ~/.zshrc 后在命令行输入 mvn -versionmvn -v校验。

开始使用

认识代码仓库

  目前我们必须要了解到的两个配置(路径:你的目录/apache-maven-3.9.6/conf/settings.xml):

  1. localRepository(本地仓库):这是本地仓库目录路径,maven会自动的通过镜像地址下载依赖到本地仓库。该配置在文件中默认是注释掉的,因为它默认在${当前用户目录}/.m2/repository目录。
    该目录和.zshrc一样,都是隐藏存在的,如果是mac则可以通过如图所示的快捷键中显示所有隐藏的文件夹和文件。在这里插入图片描述
    如果是通过命令行ls -a可以显示隐藏的文件夹和文件:
apple@apples-MacBook-Pro ~ % cd ~/
apple@apples-MacBook-Pro ~ % cd .m2/repository/
apple@apples-MacBook-Pro repository % ls
antlr			commons-io		org
com			commons-lang		xmlpull
commons-collections	io
apple@apples-MacBook-Pro repository % pwd
Users/apple/.m2/repository
  1. mirrors-mirror,是执行命令时maven下载依赖的网址。默认该配置里的内容是http://0.0.0.0代表了当前你的机器的IP地址。但实际你执行命令它默认是去到自己官网去下载内容。在这里插入图片描述
  2. 通常我们会改变1.(你希望存放的路径)2.(你需要更快的下载速度)的配置。第一点不用说,改变路径即可。第二点通常我们要配置国内的网站。比如:aliyun
<mirror>        
 <id>alimaven</id>
 <name>aliyun-maven</name>
 <mirrorOf>central</mirrorOf>
 <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
  1. 如果不修改此位置很可能使用mvn命令时是卡顿的,因为毕竟官网是国外站点。在这里插入图片描述
  2. 修改后执行时下载依赖的站点在这里插入图片描述

使用命令行来创建项目

mvn archetype:generate

archetype?:使用不同的项目原型(目录结构和必须的文件,比如jar和war的结构是不一样的)来建立项目。

  1. 按照默认的样本输入1创建
    在这里插入图片描述

  groupId?:要理解这一点我们必须观察该命令的执行结果mvn dependency:get -DremoteRepositories=http://maven.aliyun.com/nexus/content/groups/public -DgroupId=mysql -DartifactId=mysql-connector-java -Dversion=8.0.33

  1. 通过mvn dependency:get 复制远程镜像的依赖到本地,
  2. DremoteRepositories是远程地址。

前面setting配置文件中localRepository的目录,找到mysql在这里插入图片描述
groupId是包前缀:包前缀通常是公司名称,.间隔后到本地会是以.间隔为目录,比如:。在这里插入图片描述

com通常作为一家企业的默认的前缀,所以我们在上面的命令行中提示的groupId中输入com.edu.samuel在这里插入图片描述

artifactId:就是在mysql目录中的mysql-connector-java,在java中项目名称也都通过词与词之间小写化+-来作为项目名称。也就是说groupId通常作用于是哪个公司,哪个项目组来完成的。在这里插入图片描述

version:在软件的世界中通常使用x.x.x来标识一个版本,第一个x表达大进化,其次依次是更小的变动,其中这个界限在哪里,没有硬性的规定,某个团队中或许会有明确的要求。

package:打包时的jar或war文件名称。输入后继续输入y来完成提示内容。在这里插入图片描述在这里插入图片描述

pom.xml

apple@apples-MacBook-Pro lesson1 % pwd  
/Users/apple/lesson1
apple@apples-MacBook-Pro lesson1 % ls
pom.xml	src
apple@apples-MacBook-Pro main % cat 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.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.edu.samuel</groupId>
  <artifactId>lesson1</artifactId>
  <version>0.0.1</version>
  <name>Archetype - lesson1</name>
  <url>http://maven.apache.org</url>
</project>
  1. pom.xml主要是配置依赖生命周期中使用的组件的配置文件,它将指导着你希望如何构建这个项目。
  2. 刚才我们有一个谜题还没得到验证,就是package的执行结果
  3. 我们最开始选择了根据默认创建的模型创建项目,所以这里在该目录下执行mvn package在这里插入图片描述
  4. package周期执行完成(在不修改任何pom.xml内容)时的执行结果会有一个target目录,查看该目录结果,classes目录是所有你可以直接查看的class文件, 在这里插入图片描述
  5. lesson1-0.0.1.jar则是需要通过jd-gui打开JD-GUI
  6. 我们执行mvn install,前面说过,它是打包到本地的包仓库。而mvn package只是在当前目录下生成了编译后的class与jar。在这里插入图片描述
  7. 所以到这里install命令的意义是,将这个目录公布到仓库中,让其它协作的人员或团队能够同样通过maven配置的方式引用到你的最新内容。
  8. 而打包的jar名字是通过pom.xml中的<name>Archetype - lesson1</name>来确定的。

依赖

  我们将刚才新建的项目中的pom.xml内容修改为(添加了mysql的依赖):

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.edu.samuel</groupId>
  <artifactId>lesson1</artifactId>
  <version>0.0.1</version>
  <name>Archetype - lesson1</name>
  <url>http://maven.apache.org</url>
<dependencies>
 <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
</dependency>
</dependencies>
</project>

此时你会发现执行package命令结果,并不如你所愿,因为刚才我们说过,maven只是规定了生命周期但是具体怎么做,仍然需要你添加更多的配置(指定):在这里插入图片描述

build -> plugins -> plugin

 我们来实现一个自己的工作过程添加到maven中,通过这个过程理解plugin。

  1. 通过idea打开该工程:在这里插入图片描述

  2. 在pom.xml中添加依赖(我们需要实现maven提供的生命周期接口,注意dependenciesdependency的复数,所以dependency在dependencies之下)。

<dependency>
    <groupId>org.apache.maven</groupId>
     <artifactId>maven-plugin-api</artifactId>
     <version>3.0</version>
 </dependency>
 <dependency>
     <groupId>org.apache.maven.plugin-tools</groupId>
     <artifactId>maven-plugin-annotations</artifactId>
     <version>3.5</version>
 </dependency>
  1. 如果报错(红色)通过mvn dependency:resolve在pom.xml文件命令行下,下载依赖到本地仓库(此时可以观察org.apache.maven.plugin-tools在目录中的构成,这是理解groupId处理很好的例子)。在这里插入图片描述
  2. 完整执行后我们的依赖会是如下:在这里插入图片描述
  3. 编写我们自定义的插件类(注意是package周期时的,这意味着clean周期不会执行)
package test.maven.plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
@Mojo(name = "myLifeCycle", defaultPhase = LifecyclePhase.PACKAGE)//LifecyclePhase.PACKAGE="package"
public class MyLifeCycle extends AbstractMojo {
    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("Custom plugin exec");
    }
}
配置自定义插件到周期中我们需要干两件事情
将我们的插件install到本地仓库中
  1. 定义java
package test.maven.plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
@Mojo(name = "myLifeCycle", defaultPhase = LifecyclePhase.PACKAGE)//LifecyclePhase.PACKAGE="package"
public class MyLifeCycle extends AbstractMojo {
    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("Custom plugin exec");
    }
}
  1. 修改pom.xml(请注意packagingplugin中的内容,因为本该使用两个工程一个是插件plugin工程install后,然后从另外一个工程中引入该插件在maven的世界中一切皆是dependency“依赖”
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.edu.samuel</groupId>
    <artifactId>lesson1</artifactId>
    <version>0.0.1</version>
    <packaging>maven-plugin</packaging>
    <name>Archetype - lesson1</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 配置插件用的插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.5.2</version>
                <configuration>
                    <!-- 插件执行命令前缀 -> mvn prefix:mojoName,例: mvn customPlugin:customMojo -->
                    <goalPrefix>myLifeCycle</goalPrefix>
                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  1. 通过install来打包当前的plugin版本,目的是为了后面引入。
引入插件

   上一个小目录中我们强调了本该应该使用两个工程。而我们现在使用一个工程示例,所以必须先通过install把plugin工程的内容打包到maven的本地仓库中。然后在我们测试该插件时引入它。
   此时我们将lesson1工程复制重命名为lesson2并且修改pom.xml为(请注意artifactId,以及plugins的区别”刚在是定义自己的插件,现在是引入“),并且MyLifeCycle.java在当前lesson2工程中是可以删除的:

<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/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.edu.samuel</groupId>
   <artifactId>lesson2</artifactId>
   <version>0.0.1</version>
   <name>Archetype - lesson2</name>
   <packaging>jar</packaging>
   <url>http://maven.apache.org</url>
   <build>
       <plugins>
           <plugin>
               <groupId>com.edu.samuel</groupId>
               <artifactId>lesson1</artifactId>
               <version>0.0.1</version>
               <executions>
                   <execution>
                       <!-- 执行id -->
                       <id>myLifeCycle</id>
                       <!-- 生效阶段,不指定则取插件类的@Mojo注解中的defaultPhase。此处专门设定了一个与defaultPhase不同的阶段值 -->
                       <phase>package</phase>
                       <!-- 需要运作的Goal -->
                       <goals>
                           <goal>myLifeCycle</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
       </plugins>
   </build>
</project>

  此时我们在lesson2工程目录中的命令行执行 mvn package时就会出现Custom plugin exec了:在这里插入图片描述

如果输入clean命令不会出现该内容:在这里插入图片描述

输入install命令是会出现,因为install生命周期包含了package:在这里插入图片描述

引入三方库并且打包到内容中

  除非必要的情况之下,大多数场景都已经实现了你需要的。比如我们刚才没有解决的问题:打包时将mysql一起打包。你可以理解为assembly插件为你做了这个事情,所以我们修改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.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.edu.samuel</groupId>
    <artifactId>lesson2</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>
    <name>Archetype - lesson2</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.3</version>
                <executions>
                    <execution>
                        <id>make-assembly</id><!--名字任意 -->
                        <phase>package</phase><!-- 绑定到package生命周期阶段上 -->
                        <goals>
                            <goal>single</goal><!-- 该打包任务只运行一次 -->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

  此时我们如果是执行mvn package可以在工程内的target目录中发现lesson2-0.0.1.jarlesson2-0.0.1-jar-with-dependencies.jar两个文件,我们可以使用JD-GUI工具打开它们看看,如果是with-dependencies是包含了mysql依赖的:在这里插入图片描述

IDEA打开MAVEN工程

src/main

该目录是所有存放正式代码配置,和它相对的还有src/test。

  1. 但是我们可以通过jd-gui发现src main并没有作为最终的编译结果目录(它把src/main丢失掉了)。
  2. src是源码目录
  3. resource包含着所有除.java以外的一切文件(通过打包时的结构,在java中的使用不同,建议研究一下java流与jar文件目录结构,在此不做追溯)。
  4. target目录是所有的编译结果目录可以直接查看,不像jar需要通过jd-gui。比如classes:是所有变异后的源码(.class)。
  5. target目录下每次通过mvn package命令时会更新,当然了mvn install生命周期包含了package,所以也会更新:在这里插入图片描述

IDEA新建MAVEN工程

在IDEA中FILE->PROJECT->NEW PROJECT中:

  1. 新建输入Name,Name默认会被作为MAVEN中的ArtifactId
  2. 选择build system是maven
  3. GroupId在我们初步学习中其实也并不需要特别的在意,但在实际工作时定义它的名字取决于你对该项目的认识认知与个人水平。
    在这里插入图片描述

Maven Archetype

  1. mac默认目录一样,都是在/Users/apple
    在这里插入图片描述
  2. Catalog标识了有哪些源,从哪里拉取继续下面的配置。 在这里插入图片描述
  3. Archetype 和上面命令行新建项目时一样,是什么样的项目类型
    • 简单项目
    • j2ee项目 在这里插入图片描述

IDEA 配置MAVEN

  如果你刚才尝试了新建maven项目,那么你一定发现idea执行的maven不是我们前面配置的仓库地址,这是因为它自己也自带一个maven。在Perferences中可以通过搜索找到MAVEN:

  1. 覆盖 Maven home path
  2. 覆盖setting.xml
  3. repositoryOverrride看情况,比如我默认的目录就是在此。(MAC中没有系统磁盘C盘的概念)
    在这里插入图片描述
    在这里插入图片描述

IDEA中操作MAVEN生命周期

  1. 添加了mysql与alibaba druid的依赖,mysql本次仓库已经拥有了该依赖所以没有报错。
  2. 打开在界面右侧的maven,执行verify周期即可。
  3. 其它生命周期都同理,它都以~/EDU-Samuel为基准目标
    在这里插入图片描述

MAVEN依赖配置的总库

https://mvnrepository.com/是MAVEN仓库的全球基础,所有的国内镜像在找不到依赖时最终访问的还是它,所以我们在需要依赖时完全可以在这里搜索:

  1. 但是国内比如阿里的镜像到达你的网络是快速的
  2. 而它到达国外站点拥有专有通道而已
  3. 所以它们之间并没有本质区别

mvn idea:idea

mvn idea:idea是重新生成在idea中的结构命令,当你添加新的依赖后(或者修改什么其它maven配置后)执行了verity,依然在idea中的 External Libraries 没有找到你的依赖的话。说明idea没有识别到你的修改。我们可以通过如下两种方式:

  1. 通过idea操作maven reload
    在这里插入图片描述
  2. 在项目目录下执行 mvn idea:idea
  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值