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

本篇通过一个最基础的入门案例,熟悉一下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{@Testpublic 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.mzph.cn/news/628549.shtml

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

相关文章

【用队列实现栈】【用栈实现队列】Leetcode 232 225

【用队列实现栈】【用栈实现队列】Leetcode 232 225 队列的相关操作栈的相关操作用队列实现栈用栈实现队列 ---------------&#x1f388;&#x1f388;题目链接 用队列实现栈&#x1f388;&#x1f388;------------------- ---------------&#x1f388;&#x1f388;题目链…

TCP 的三次握手和四次挥手

Java 面试题 TCP 三次握手 第一次握手&#xff1a;客户端向服务端发送SYN包。报文中标志位SYN1&#xff0c;序列号seqx&#xff08;x为随机整数&#xff09;。此时客户端进入了 SYN_SEND 同步已发送状态。 第二次握手&#xff1a;服务端回复客户端SYNACK包。报文中标志位SYN1&…

宿舍管理系统的设计与实现:基于Spring Boot、Java、Vue.js和MySQL的完整解决方案

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

文理导航期刊投稿方式

《文理导航》杂志系国家新闻出版总署批准&#xff0c;内蒙古自治区文旅厅主管&#xff0c;内蒙古自治区北方文化研究院主办的&#xff0c;面向大中专院校、中小学教育的专业性教育刊物&#xff0c;阅读对象是关心教育事业发展的大中专院校、职业教育、中小学教育的专家、教研员…

Flask框架小程序后端分离开发学习笔记《1》网络知识

Flask框架小程序后端分离开发学习笔记《1》网络知识 Flask是使用python的后端&#xff0c;由于小程序需要后端开发&#xff0c;遂学习一下后端开发。 一、网址组成介绍 协议&#xff1a;http&#xff0c;https (https是加密的http)主机&#xff1a;g.cn zhihu.com之类的网址…

嵌入式-Stm32-江科大基于寄存器点亮LED灯

文章目录 前言&#xff1a;一&#xff1a;搭建基于寄存器控制LED的工程二&#xff1a;用江科大的STM32板子实现基于寄存器点亮LED灯三&#xff1a;用非江科大stm32板子实现基于寄存器点亮LED灯道友&#xff1a;一星陨落&#xff0c;黯淡不了星空灿烂&#xff1b;一花凋零&#…

Flume 之自定义 Source

1、简介 Flume 自带 Source 有 Avro、Thrift、Netcat、Taildir、Kafka、Http等&#xff0c;有些场合比如我们指定访问接口获取数据当做 Flume 的 Source&#xff0c;像这种定制化的 Source 需要我们自己实现&#xff0c;下面我将介绍如何自定义实现 Source。 2、自定义实现 Fl…

Git 是什么?

Git 是什么&#xff1f; Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;…

Cesium 模型压平

最近整理了下手上的代码&#xff0c;以下是对模型压平的说明。 原理是使用了customShader来重新设置了模型的着色器&#xff0c;通过修改模型顶点的坐标来实现了压平。 废话不多说&#xff0c;下面上代码&#xff1a; /*** class* description 3dtiles模型压平*/ class Flat…

推荐给前端程序员的5款浏览器插件

所谓“工欲善其事&#xff0c;必先利其器”。Chrome&#xff08;谷歌浏览器&#xff09; 应该是程序员或者互联网行业人员使用最多的浏览器了。而在日常开发中&#xff0c;下面几款 浏览器 扩展也许能让你的开发工作事半功倍 。 1、Vimium vimium 是一个旨在将你的双手从鼠标…

C++核心编程(包含:内存、函数、引用、类与对象、文件操作等)【持续更新】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;C从基础到进阶 C核心编程&#x1f30f;1 内存分区模型&#x1f384;1.1 程序运行前&#x1f384;1.2 程序运行后&#x1f384;1.3 new操作符 &#x1f30f;2 引用&#x1f384;2.1 引用的基…

【Golang开源项目】Golang高性能内存缓存库BigCache设计与分析

项目地址 BigCache 是一个快速&#xff0c;支持并发访问&#xff0c;自淘汰的内存型缓存&#xff0c;可以在存储大量元素时依然保持高性能。BigCache将元素保存在堆上却避免了GC的开销。 背景介绍 BigCache的作者在项目里遇到了如下的需求&#xff1a; 支持http协议支持 10…

Linux shell编程学习笔记39:df命令

0 前言1 df命令的功能、格式和选项说明 1.1 df命令的功能1.2 df命令的格式1.3 df命令选项说明 2 df命令使用实例 2.1 df&#xff1a;显示主要文件系统信息2.2 df -a&#xff1a;显示所有文件系统信息2.3 df -t[]TYPE或--type[]TYPE&#xff1a;显示TYPE指定类型的文件系统信…

解决英特尔无线网卡WiFi或者蓝牙突然消失问题

winR&#xff0c;输入“devmgmt.msc”&#xff0c;检查设备管理器中的无线网卡驱动是否安装好。 访问https://www.intel.cn/content/www/cn/zh/download/19351/windows-10-and-windows-11-wi-fi-drivers-for-intel-wireless-adapters.html下载对应系统版本的英特尔无线网卡WiFi…

遇到问题不要慌,轻松搞定内存泄露

当一个系统在发生 OOM 的时候&#xff0c;行为可能会让你感到非常困惑。因为 JVM 是运行在操作系统之上的&#xff0c;操作系统的一些限制&#xff0c;会严重影响 JVM 的行为。故障排查是一个综合性的技术问题&#xff0c;在日常工作中要增加自己的知识广度。多总结、多思考、多…

基于PyQT的图片批处理系统

项目背景&#xff1a; 随着数字摄影技术的普及&#xff0c;人们拍摄和处理大量图片的需求也越来越高。为了提高效率&#xff0c;开发一个基于 PyQt 的图片批处理系统是很有意义的。该系统可以提供一系列图像增强、滤波、水印、翻转、放大缩小、旋转等功能&#xff0c;使用户能够…

SpringBoot:详解依赖注入和使用配置文件

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、&#x1f3…

力扣精选算法100题——等于目标值的两个数or三数之和(双指针专题)

目录 &#x1f6a9;等于目标值的俩个数 第一步&#xff1a;了解题意 第二步&#xff1a;算法原理 第三步&#xff1a;代码实现 &#x1f6a9;三数之和 第一步&#xff1a;了解题意 第二步&#xff1a;算法原理 思路&#xff1a; ❗不漏&#xff1a; ❗去重: &#xf…

Simulink旧版本如何打开新版的模型文件

Simulink旧版本如何打开新版的模型文件 当用旧版本Simulink软件打开模型时会报错&#xff0c;是因为版本不兼容造成的 解决办法 在simulink的选项中去掉 do not load models created with newer version of Simulink

计算机视觉的应用

计算机视觉&#xff08;Computer Vision&#xff09;是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说&#xff0c;计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标&#xff0c;计算机视觉结合了图像处理、机器学习、模…