【Maven笔记3】Maven基础入门案例

news2024/9/24 5:23:50

本篇通过一个最基础的入门案例,熟悉一下maven最基础的使用方法。

编写POM

maven项目的核心是pom.xml文件,pom定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等等。
这里我们新建一个maven-demo-hello项目,并编写pom依赖:

<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>maven-demo-hello</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven-demo-hello</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
</project>

在上述pom定义中,最重要的事groupId、artifactId和version,这三个元素定了一个项目的基本坐标,在maven的世界中,任何jar、pom或war都是基于这些基本的坐标进行区分的。

  • groupId定义项目属于哪个组,一般在公司中以公司域名或组织标识组成,比如com.mycom.myapp
  • artifactId定义了当前项目在组中的唯一id,比如在上面例子中定义的是maven-demo-hello
  • version指当前项目的版本,SNAPSHOT标识快照,说明当前项目处于开发中,是不稳定的版本,随着项目迭代,version会不断更新

没有任何实际的Java代码,我们就能够定义一个Maven项目的POM,这体现了Maven的一大优点,它能让项目对象模型最大程度地与实际代码相独立,我们可以称之为解耦,或者正交性。这在很大程度上避免了Java代码和POM代码的相互影响。比如当项目需要升级版本时,只需要修改POM,而不需要更改Java代码;而在POM稳定之后,日常的Java代码开发工作基本不涉及POM的修改。

编写主代码

项目的主代码和测试代码不同,项目主代码会被打包到最终的构件中(比如jar),而测试代码只在运行测试时用到,不会被打包。按照约定,maven主代码一般放在src/main/java目录下,在该目录下创建文件org/example/App.java,内容如下:

package org.example;

/**
 * Hello world!
 *
 */
package org.example;

/**
 * Hello world!
 *
 */
public class App 
{
    public String hello(){return "Hello World";}
    
    public static void main( String[] args )
    {
        System.out.println( new App().hello() );
    }
}

使用maven进行编译,在项目根目录下运行maven命令:mvn clean compile会得到如下输出:

[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------< org.example:maven-demo-hello >--------------------
[INFO] Building maven-demo-hello 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- clean:3.2.0:clean (default-clean) @ maven-demo-hello ---
[INFO] 
[INFO] --- resources:3.3.1:resources (default-resources) @ maven-demo-hello ---
[INFO] skip non existing resourceDirectory /Users/happy/mine-code/maven-demo-hello/src/main/resources
[INFO] 
[INFO] --- compiler:3.11.0:compile (default-compile) @ maven-demo-hello ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 1 source file with javac [debug target 1.8] to target/classes
[WARNING] 未与 -source 8 一起设置引导类路径
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.006 s
[INFO] Finished at: 2024-01-07T19:36:16+08:00
[INFO] ------------------------------------------------------------------------
  • clean告诉Maven清理输出目录target/
  • compile告诉Maven编译项目主代码
  • 从输出中看到Maven首先执行了clean:clean任务,删除target/目录
  • 默认情况下,Maven构建的所有输出都在target/目录中
  • 接着执行resources:resources任务(未定义项目资源,暂且略过)
  • 最后执行compiler:compile任务,将项目主代码编译至target/classes目录

上文提到的clean:clean、resources:resources和compiler:compile对应了一些Maven插件及插件目标,比如clean:clean是clean插件的clean目标,compiler:compile是compiler插件的compile目标

除了使用maven命令的方式运行maven项目之外,日常开发中使用IDE,可以直接界面上操作即可,如图:
在这里插入图片描述

编写测试代码

Maven项目中默认的测试代码目录是src/test/java,测试代码需要使用到JUnit,这里我们需要引入JUnit的依赖,在pom中添加依赖:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

有了这段依赖,maven自动下载junit包,具体从哪里下载取决于maven配置,一般在企业中会有对应的私服仓库地址

上述POM代码中还有一个值为test的元素scope,scope为依赖范围,若依赖范围为test则表示该依赖只对测试有效。换句话说,测试代码中的import JUnit代码是没有问题的,但是如果在主代码中用import JUnit代码,就会造成编译错误。

如果不声明依赖范围,那么默认值就是compile,表示该依赖对主代码和测试代码都有效。

编写单元测试,代码如下:

package org.example;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

/**
 * Unit test for simple App.
 */
public class AppTest{

    @Test
    public void helloTest(){
        App app = new App();
        String result = app.hello();
        assertEquals("Hello World", result);
    }
}

使用maven命令执行测试,运行:mvn clean test,输出如下:

[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------< org.example:maven-demo-hello >--------------------
[INFO] Building maven-demo-hello 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- clean:3.2.0:clean (default-clean) @ maven-demo-hello ---
[INFO] Deleting /Users/happy/mine-code/maven-demo-hello/target
[INFO] 
[INFO] --- resources:3.3.1:resources (default-resources) @ maven-demo-hello ---
[INFO] skip non existing resourceDirectory /Users/happy/mine-code/maven-demo-hello/src/main/resources
[INFO] 
[INFO] --- compiler:3.11.0:compile (default-compile) @ maven-demo-hello ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 1 source file with javac [debug target 1.8] to target/classes
[WARNING] 未与 -source 8 一起设置引导类路径
[INFO] 
[INFO] --- resources:3.3.1:testResources (default-testResources) @ maven-demo-hello ---
[INFO] skip non existing resourceDirectory /Users/happy/mine-code/maven-demo-hello/src/test/resources
[INFO] 
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ maven-demo-hello ---
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 1 source file with javac [debug target 1.8] to target/test-classes
[WARNING] 未与 -source 8 一起设置引导类路径
[INFO] 
[INFO] --- surefire:3.1.2:test (default-test) @ maven-demo-hello ---
[INFO] Using auto detected provider org.apache.maven.surefire.junit4.JUnit4Provider
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.example.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.072 s -- in org.example.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.165 s
[INFO] Finished at: 2024-01-07T20:13:30+08:00
[INFO] ------------------------------------------------------------------------

可以看到compiler:testCompile,surefire:test插件运行成功,并输出了测试报告,显示一共运行了多少测试,失败多少,出错了多少,跳过多少。

打包和运行

项目编译、测试都通过之后,下一个重要步骤就是打包(package)。本项目pom中没有指定打包类型,使用默认的打包类型jar。

使用maven命令:mvn clean package 进行打包,输出如下:

[INFO] --- jar:3.3.0:jar (default-jar) @ maven-demo-hello ---
[INFO] Building jar: /Users/happy/mine-code/maven-demo-hello/target/maven-demo-hello-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.015 s
[INFO] Finished at: 2024-01-07T20:24:22+08:00
[INFO] ------------------------------------------------------------------------

类似地,在执行打包之前,会先执行编译、测试等操作,这里看到jar:jar任务负责打包,实际上就是jar插件的jar目标将项目主代码打包成一个名为maven-demo-hello-1.0-SNAPSHOT.jar的文件。

至此,我们拿到了整个项目的输出,可以通过maven命令:mvn clean install 命令将输出的构件安装到本地仓库,这样其他项目也可以使用该构件。在企业中,一般会通过流水线或构建平台等将包发布到企业私有仓库中。

默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中(打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。为了生成可执行的jar文件,需要借助maven-shade-plugin,在pom中配置该插件如下:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>
                    org.example.App
                  </mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

再次运行maven打包命令:mvn clean package,输出如下:

[INFO] --- jar:3.3.0:jar (default-jar) @ maven-demo-hello ---
[INFO] Building jar: /Users/happy/mine-code/maven-demo-hello/target/maven-demo-hello-1.0-SNAPSHOT.jar
[INFO] 
[INFO] --- shade:1.2.1:shade (default) @ maven-demo-hello ---
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /Users/happy/mine-code/maven-demo-hello/target/maven-demo-hello-1.0-SNAPSHOT.jar with /Users/happy/mine-code/maven-demo-hello/target/maven-demo-hello-1.0-SNAPSHOT-shaded.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.223 s
[INFO] Finished at: 2024-01-07T20:40:00+08:00
[INFO] ------------------------------------------------------------------------

可以看到maven-demo-hello-1.0-SNAPSHOT.jar和original-maven-demo-hello-1.0-SNAPSHOT.jar,前者是带有Main-Class信息的可运行jar,后者是原始的jar。

运行jar包:

➜  target java -jar maven-demo-hello-1.0-SNAPSHOT.jar 
Hello World
➜  target java -jar original-maven-demo-hello-1.0-SNAPSHOT.jar 
original-maven-demo-hello-1.0-SNAPSHOT.jar中没有主清单属性

【Maven笔记1】Maven介绍
【Maven笔记2】Maven安装与配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1365025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS Code结合Live Server插件快速搭建小游戏并发布至公网可随时远程访问

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…

黑莓系统的安全性如何?

黑莓系统的安全性非常高&#xff01; 在过去很长一段时间里&#xff0c;都被认为是手机市场上最安全的操作系统。这主要得益于黑莓在安全性方面的重视和投入。 &#xff08;在世界上最安全的 6 款手机排名中&#xff0c;iPhone未能入围&#xff09; 世界上最安全的 6 款手机&…

CNN——ResNet

深度残差网络&#xff08;Deep residual network, ResNet&#xff09;的提出是CNN图像史上的一件里程碑事件&#xff0c;并且让深度学习真正可以继续做下去&#xff0c;斩获2016 CVPR Best Paper。此外ResNet的作者都是中国人&#xff0c;一作何恺明。ResNet被提出以后很多的网…

Mac 16g约等于Windows多少g?

Mac 16g 内存等于 Windows 320g 内存 何为“黄金内存”&#xff1f; Mac 的内存是用黄金做的&#xff0c;而 Windows 的内存是用铁做的。 黄金的密度是 19.32 g/cm&#xff0c;而铁的密度是 7.874 g/cm。 因此&#xff0c;16g 的黄金体积是 0.082 cm&#xff0c;而 16g 的铁…

交换机_05VLAN

一、VLAN技术的引入 VLAN&#xff08;Virtual Lan&#xff09;主要应用在交换机上 一台交换机默认情况下连接一个广播域&#xff0c;因为默认情况下所有的接口都是属于同一个vlan的&#xff0c;默认vlan1&#xff0c;所以是在同一个广播域中。 结合交换机工作原理&#xff0…

Python 利用PYQT5设计基于RSA算法盲签名的匿名化电子支付系统设计与实现

基于RSA算法的盲签名算法 David Chaum 于1982年提出盲签名的概念&#xff0c;并利用RSA算法设计了第一个盲签名方案. 该方案的安全性基于大整数分解问题 盲签名的步骤 1.密钥生成 签名者执行以下步骤生成密钥对: ①签名者选择两个大素数p,q&#xff0c; 计算npq&#xff0…

OpenCV-18图像的翻转和旋转

一、图像的翻转 使用API---cv.flip&#xff08;src, flipCode&#xff09; flipCode 0表示上下翻转 flipCode > 0表示左右翻转 flipCode < 0上下 左右翻转 或者使用np的翻转src[: : -1,: : -1]实现上下翻转。 示例代码如下&#xff1a; import cv2 import numpy…

GPT(Generative Pre-Training)论文解读及源码实现(二)

本篇为gpt2的pytorch实现&#xff0c;参考 nanoGPT nanoGPT如何使用见后面第5节 1 数据准备及预处理 data/shakespeare/prepare.py 文件源码分析 1.1 数据划分 下载数据后90%作为训练集&#xff0c;10%作为验证集 with open(input_file_path, r) as f:data f.read() n …

yolo 分割label格式标注信息图片显示可视化查看

参考: https://github.com/ultralytics/ultralytics/issues/3137 https://blog.csdn.net/weixin_42357472/article/details/135218349?spm=1001.2014.3001.5501 需要把坐标信息在图片上显示 代码 1)只画出了坐标边缘 import cv2 import numpy as np from random impor…

html 原生网页使用ElementPlus 日期控件el-date-picker换成中文

项目&#xff1a; 原生的html,加jQuery使用不习惯&#xff0c;新html页面导入vue3,element plus做界面&#xff0c;现在需要把日历上英文切成中文。 最终效果&#xff1a; 导入能让element plus日历变成中文脚本&#xff1a; elementplus, vue3对应的js都可以通过创建一个vu…

idea 以文本形式输出 SpringBoot项目 目录结构

第1步&#xff1a;AltF12 打开 Terminal 终端 第2步&#xff1a;cd 到 项目路径下 第3步&#xff1a;使用 tree 命令 结果 D:. ├─.mvn │ └─wrapper ├─applog │ └─logs ├─src │ ├─main │ │ ├─java │ │ │ └─com │ │ │ └─zhangziwa …

【软件测试】学习笔记-如何做好单元测试

什么是单元测试&#xff1f; 在正式开始今天的话题之前&#xff0c;我先给你分享一个工厂生产电视机的例子。 工厂首先会将各种电子元器件按照图纸组装在一起构成各个功能电路板&#xff0c;比如供电板、音视频解码板、射频接收板等&#xff0c;然后再将这些电路板组装起来构…

【计算机网络】网络编程套接字socket--UDP/TCP简单服务器实现/TCP协议通信流程

文章目录 一、预备知识1.IP和端口号2.TCP协议和UDP协议3.网络字节序 二、socket编程接口1.socket 常见API2.sockaddr结构 三、UDP服务器相关重要接口介绍sendtorecvfrompopen 1.udpServer.hpp2.udpServer.cc3.udpClient.hpp4.udpClient.cc5.onlineUser.hpp 四、TCP服务器socket…

高性能、可扩展、分布式对象存储系统MinIO的介绍、部署步骤以及代码示例

详细介绍 MinIO 是一款流行的开源对象存储系统&#xff0c;设计上兼容 Amazon S3 API&#xff0c;主要用于私有云和边缘计算场景。它提供了高性能、高可用性以及易于管理的对象存储服务。以下是 MinIO 的详细介绍及优缺点&#xff1a; 架构与特性&#xff1a; 开源与跨平台&am…

HTML---JavaScript操作DOM对象

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 本章目标 了解DOM的分类和节点间的关系熟练使用JavaScript操作DOM节点 访问DOM节点 能够熟练的进行节点的创建、添加、删除、替换等 能够熟练的设置元素的样式 能够灵活运用JavaScript获取元素…

SpringBoot学习(八)-SpringBoot + Dubbo + zookeeper

分布式DubboZookeeper 1、分布式理论 1&#xff09;什么是分布式系统&#xff1f; 在《分布式系统原理与范型》一书中有如下定义&#xff1a;“分布式系统是若干独立计算机的集合&#xff0c;这些计算机对于用户来说就像单个相关系统”&#xff1b; 分布式系统是由一组通过…

【AI视野·今日CV 计算机视觉论文速览 第284期】Fri, 5 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Fri, 5 Jan 2024 Totally 62 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Learning to Prompt with Text Only Supervision for Vision-Language Models Authors Muhammad Uzair Khattak, Muhammad F…

2024.1.7-实战-docker方式给自己网站部署prometheus监控ecs资源使用情况-2024.1.7(测试成功)

实战-docker方式给自己网站部署prometheus监控ecs资源使用情况-2024.1.7(测试成功) 目录 最终效果 原文链接 https://onedayxyy.cn/docs/prometheus-grafana-ecs 参考模板 https://i4t.com/ https://grafana.frps.cn &#x1f530; 额&#xff0c;注意哦: 他这个是通过frp来…

【Flutter 开发实战】Dart 基础篇:从了解背景开始

想要学会用 Flutter 开发 App&#xff0c;就不可避免的要学习另一门很有意思的编程语言 —— Dart。很多小伙伴可能在学习 Flutter 之前可能都没听说过这门编程语言&#xff0c;我也是一样&#xff0c;还以为 Dart 是为了 Flutter 而诞生的&#xff1b;然而&#xff0c;当我们去…

网页设计与制作web前端设计html+css+js成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站(HTML静态网页项目实战)附源码】

网页设计与制作web前端设计htmlcssjs成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站&#xff08;HTML静态网页项目实战&#xff09;附源码】 https://www.bilibili.com/video/BV1Hp4y1o7RY/?share_sourcecopy_web&vd_sourced43766e8ddfffd1f1a1165a3e72d7605