简单的说就是 maven 是一个项目管理工具,同时也是一个依赖管理工具。
使用 maven 生成的项目结构大致如下:
project
|- src/main/java
|- src/main/resources
|- src/test/java
|- src/test/resources
本篇笔记带一些核心重点和在 maven 中创建一个项目
这里主要是用终端运行,指令包括构建 maven 项目、查看 pom 文件以及显示 maven 项目的结构,如下:
❯ mvn archetype:generate -DgroupId=com.goldenaarcher -DartifactId=hellomaven -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
# 如果是第一次下载会花一点时间
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /Users/usr/study/maven
[INFO] Parameter: package, Value: com.goldenaarcher
[INFO] Parameter: groupId, Value: com.goldenaarcher
[INFO] Parameter: artifactId, Value: hellomaven
[INFO] Parameter: packageName, Value: com.goldenaarcher
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/usr/study/maven/hellomaven
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34.244 s
[INFO] Finished at: 2023-09-11T08:18:15-04:00
[INFO] ------------------------------------------------------------------------
# 查看 pom 文件
❯ cat hellomaven/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.goldenaarcher</groupId>
<artifactId>hellomaven</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>hellomaven</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
# 查看项目结构
❯ tree hellomaven
hellomaven
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── goldenaarcher
│ └── App.java
└── test
└── java
└── com
└── goldenaarcher
└── AppTest.java
10 directories, 3 files
artifactId 和项目名相同,指令做什么后面会进行解释
这里主要是将 repositories 上的依赖打包下载到本地的 .m2 文件夹中,然后再根据 pom 文件进行管理:
❯ mvn install
[INFO] Compiling 1 source file to /Users/usr/study/maven/hellomaven/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] Source option 5 is no longer supported. Use 7 or later.
[ERROR] Target option 5 is no longer supported. Use 7 or later.
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.731 s
[INFO] Finished at: 2023-09-11T09:35:01-04:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project hellomaven: Compilation failure: Compilation failure:
[ERROR] Source option 5 is no longer supported. Use 7 or later.
[ERROR] Target option 5 is no longer supported. Use 7 or later.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
这其中会出现一些小问题,主要是默认的 java 版本太老(5),现在已经不支持,所以要根据项目安装并配置对应的 java 版本。这里的 pom 文件会在 properties 里面配置 java 的版本:
<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.0modelVersion>
<groupId>com.goldenaarchergroupId>
<artifactId>hellomavenartifactId>
<packaging>jarpackaging>
<version>1.0-SNAPSHOTversion>
<name>hellomavenname>
<url>http://maven.apache.orgurl>
<properties>
<maven.compiler.source>17maven.compiler.source>
<maven.compiler.target>17maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
dependencies>
project>
然后重新安装:
❯ mvn install
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hellomaven ---
[INFO] Building jar: /Users/usr/study/maven/hellomaven/target/hellomaven-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hellomaven ---
[INFO] Installing /Users/usr/study/maven/hellomaven/target/hellomaven-1.0-SNAPSHOT.jar to /Users/usr/.m2/repository/com/goldenaarcher/hellomaven/1.0-SNAPSHOT/hellomaven-1.0-SNAPSHOT.jar
[INFO] Installing /Users/usr/study/maven/hellomaven/pom.xml to /Users/usr/.m2/repository/com/goldenaarcher/hellomaven/1.0-SNAPSHOT/hellomaven-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.128 s
[INFO] Finished at: 2023-09-11T09:38:45-04:00
[INFO] ------------------------------------------------------------------------
❯ tree hellomaven
hellomaven
├── pom.xml
├── src
│ ├── main
│ │ └── java
│ │ └── com
│ │ └── goldenaarcher
│ │ └── App.java
│ └── test
│ └── java
│ └── com
│ └── goldenaarcher
│ └── AppTest.java
└── target
├── classes
│ └── com
│ └── goldenaarcher
│ └── App.class
├── generated-sources
│ └── annotations
├── generated-test-sources
│ └── test-annotations
├── hellomaven-1.0-SNAPSHOT.jar
├── maven-archiver
│ └── pom.properties
├── maven-status
│ └── maven-compiler-plugin
│ ├── compile
│ │ └── default-compile
│ │ ├── createdFiles.lst
│ │ └── inputFiles.lst
│ └── testCompile
│ └── default-testCompile
│ ├── createdFiles.lst
│ └── inputFiles.lst
├── surefire-reports
│ ├── TEST-com.goldenaarcher.AppTest.xml
│ └── com.goldenaarcher.AppTest.txt
└── test-classes
└── com
└── goldenaarcher
└── AppTest.class
29 directories, 13 files
.m2 在的位置系统不同,目录不同,可以根据自己的系统找找对应的资料
❯ java -cp target/hellomaven-1.0-SNAPSHOT.jar com.goldenaarcher.App com.goldenaarcher.App
Hello World!
最后就使用 java -cp 的指令运行一下打包好的 class 文件即可
基础的语法为:plugin-prefix:goal,如 mvn compiler:compile,这里的插件就是 compiler,goal 就是 compile, mvn clean:clean 同理
plugins 是一个或多个相关任务(task)的集合,比如说一直使用的 mvn clean 中的 plugin 就是 maven-clean-plugin,运行 mavn clean 的时候实际上指定的是 maven-clean-plugin 中的 clean goal(也叫 MOJO)
比较常见的 maven goal 有 来自 mmaven-compiler-plugin 的 compile, maven-surefire-plugin 中的 test,来自各种不同插件中的 package(war 和 jar 的插件就不一样),以及上面提到的 clean。
parameters 就是上面使用的如 -DgroupId=com.goldenaarcher,语法为 -D,这个 param 意思就是指定 groupId 为 com.goldenaarcher
POM 是 Project Object Mode,是 maven 最基础的工作组件。
maven 的生命周期有三个:
default
管理项目的部署
clean
管理项目的清理
site
管理项目文档网页的创建
生命周期主要是定义 goal 执行的顺序,以便可以完成特定的 task,官方文档说的更直接,就是说……只要学一点指令 POM 就保证结果令人满意
phase 是 lifecycle 的步骤,每个 phase 代表了生命周期特定的阶段
官方文档中是提供了 default 中的一些 phase,如:
validate
验证项目结构是否正确,所有必要信息是否都有提供
compile
编译源代码
test
更具对应的测试框架执行源码的测试,这段代码不应当被打包到部署中去
顺便这一步可跳过
package
将编译好的源码和包打包成合适的格式,如 jar、war
verify
执行一些必要的集成测试区保证包的合规性和质量
install
安装所有需要的依赖,这可以是从 central repo 上拉下来的,也可以是本地的项目
deploy
在打包环境下完成,将最终成品包覆知道远程 repo 进行共享
当单独执行某一个 phase 的时候,其前置 phase 也会被执行,如执行 mvn package,它也会先执行 validate, compile, test
每个打包阶段都是由不同的 goal 构成的,但是 goal 具有可以被单独运行的独立性,而不需要单独打包到指定的 lifecycle 中
完成先清理项目,再完成依赖的复制,最后执行打包操作的指令为:
❯ mvn clean dependency:copy-dependencies package
顺便简单说一下 clean,maven 本身会执行 clean 这个生命周期,默认情况下会执行 clean 这个 phase,这个 phase 是被绑定到 maven-clean-plugin:clean,即 插件maven-clean-plugin 上的 clean 这个 goal 上。
对于实际操作上来说,执行 maven-clean-plugin:clean 并不需要调动 clean 这个生命周期,但是反过来是不成立的。
coordinates 指的就是一些可以辨识项目的集合,它又以下几个部分组成:
groupId
通常意义上由公司域名+特有的项目名称组成,如 hadoop 的 groupId 就是 org.apache.hadoop
artifactId
打包的 jar 名称,不包含版本,如 hadoop 下的 Common 名称就是 hadoop-common
version
版本呢
packaging
指定项目的类型,如 jar、war 等,不设置的默认值为 jar
下载包的 central repo 地址, 默认的下载地址为 https://repo.maven.apache.org/maven2/
具体看各个公司,比如我们公司就在 nexus 上做了自己的镜像库
这里用 eclipse,intellij 之后搞,下载了一个 spring 插件后一直要登陆,就横帆……
选择新建一个 maven 项目

填写信息,如 maven 项目目录在哪之类的

选择创建的类型,这里用 archetypes-quickstart

填写项目信息

package 的默认名称是 group id + artifact id,可以按需修改
点击完成
这是命令行上的一些指令:
[[1;34mINFO[m] ----------------------------------------------------------------------------
[[1;34mINFO[m] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
[[1;34mINFO[m] ----------------------------------------------------------------------------
[[1;34mINFO[m] Parameter: groupId, Value: com.goldenaarcher.product
[[1;34mINFO[m] Parameter: artifactId, Value: productservices
[[1;34mINFO[m] Parameter: version, Value: 0.0.1-SNAPSHOT
[[1;34mINFO[m] Parameter: package, Value: com.goldenaarcher.product
[[1;34mINFO[m] Parameter: packageInPathFormat, Value: com/goldenaarcher/product
[[1;34mINFO[m] Parameter: package, Value: com.goldenaarcher.product
[[1;34mINFO[m] Parameter: groupId, Value: com.goldenaarcher.product
[[1;34mINFO[m] Parameter: artifactId, Value: productservices
[[1;34mINFO[m] Parameter: version, Value: 0.0.1-SNAPSHOT
[[1;34mINFO[m] Project created from Archetype in dir: /Users/usr/study/maven/productservices
[[1;34mINFO[m] [1m------------------------------------------------------------------------[m
[[1;34mINFO[m] [1;32mBUILD SUCCESS[m
[[1;34mINFO[m] [1m------------------------------------------------------------------------[m
[[1;34mINFO[m] Total time: 44.738 s
[[1;34mINFO[m] Finished at: 2023-09-11T11:04:01-04:00
[[1;34mINFO[m] [1m------------------------------------------------------------------------[m
默认的 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.0modelVersion>
<groupId>com.goldenaarcher.productgroupId>
<artifactId>productservicesartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>productservicesname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>Ï
<scope>testscope>
dependency>
dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-pluginartifactId>
<version>3.1.0version>
plugin>
<plugin>
<artifactId>maven-resources-pluginartifactId>
<version>3.0.2version>
plugin>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.0version>
plugin>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.1version>
plugin>
<plugin>
<artifactId>maven-jar-pluginartifactId>
<version>3.0.2version>
plugin>
<plugin>
<artifactId>maven-install-pluginartifactId>
<version>2.5.2version>
plugin>
<plugin>
<artifactId>maven-deploy-pluginartifactId>
<version>2.8.2version>
plugin>
<plugin>
<artifactId>maven-site-pluginartifactId>
<version>3.7.1version>
plugin>
<plugin>
<artifactId>maven-project-info-reports-pluginartifactId>
<version>3.0.0version>
plugin>
plugins>
pluginManagement>
build>
project>
可以看到 java 的版本是 1.7,这个就根据项目需求进行修改,可以直接修改 properties 里的版本,或者是用下面这个配置也可以:
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.0version>
<configuration>
<release>17release>
configuration>
plugin>
随后又见项目选择更新一下 maven 项目即可:

我是记得有个配置可以自动更新来,不知道是不是记错了
这里不太涉及 maven,带一下就过去了
感兴趣 b 站也好那里也好,找一下 servlet/spring 相关的实现也行……我暂时还没复习到那,复习了再做笔记
这里折腾的都是一些 Java 方面的配置
src/main 下的结构如下:
❯ tree productservices/src/main
productservices/src/main
└── java
└── com
└── goldenaarcher
└── product
├── dao
│ ├── ProductDAO.java
│ └── ProductDAOImpl.java
└── dto
└── Product.java
7 directories, 3 files
完整的代码如下:
Product.java
package com.goldenaarcher.product.dto;
public class Product {
private int id;
private String name;
private String description;
private int price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
ProductDAO.java
package com.goldenaarcher.product.dao;
import com.goldenaarcher.product.dto.Product;
public interface ProductDAO {
void create(Product product);
Product read(int id);
void update(Product product);
void delete(int id);
}
ProductDAOImpl.java
package com.goldenaarcher.product.dao;
import com.goldenaarcher.product.dto.Product;
public class ProductDAOImpl implements ProductDAO {
@Override
public void create(Product product) {
// TODO Auto-generated method stub
}
@Override
public Product read(int id) {
// TODO Auto-generated method stub
return null;
}
@Override
public void update(Product product) {
// TODO Auto-generated method stub
}
@Override
public void delete(int id) {
// TODO Auto-generated method stub
}
}
package com.goldenaarcher.product.dao;
import java.util.HashMap;
import java.util.Map;
import com.goldenaarcher.product.dto.Product;
public class ProductDAOImpl implements ProductDAO {
Map<Integer, Product> products = new HashMap<>();
@Override
public void create(Product product) {
products.put(product.getId(), product);
}
@Override
public Product read(int id) {
return products.get(id);
}
@Override
public void update(Product product) {
// TODO Auto-generated method stub
}
@Override
public void delete(int id) {
// TODO Auto-generated method stub
}
}
这里补一下 [JUnit] JUnit5 基础 1 - Junit5 结构 与 断言的使用 里没提到的配置,我之前知道 junit5 是有个合集,不用单独下载三四个依赖,但是找了下自己笔记里没写……
<dependencies>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-engineartifactId>
<version>5.10.0version>
<scope>testscope>
dependency>
dependencies>
版本可以选择用当前最新的稳定更新,或者这个……短期之内应该不会差太多。然后跑下 mvn clean install,有可能也需要更新 maven-surefire-plugin 这个版本去跑对应的测试
重复一下,maven-surefire-plugin 是 test 这个 goal 的插件
这里写一点测试主要是为了看下跑 mvn install 会执行测试
package com.goldenaarcher.product.dao;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import com.goldenaarcher.product.dto.Product;
public class ProductDAOImplTest {
@Test
public void createShouldCreateAProduct() {
ProductDAO dao = new ProductDAOImpl();
Product product = new Product();
product.setId(1);
product.setName("Iphone");
product.setDescription("It's awesome");
product.setPrice(800);
dao.create(product);
Product result = dao.read(1);
assertNotNull(result);
assertEquals("Iphone", result.getName());
}
}
结果:
[[1;34mINFO[m] -------------------------------------------------------
[[1;34mINFO[m] T E S T S
[[1;34mINFO[m] -------------------------------------------------------
[[1;34mINFO[m] Running com.goldenaarcher.product.dao.[1mProductDAOImplTest[m
[[1;34mINFO[m] [1;32mTests run: [0;1;32m1[m, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.018 s - in com.goldenaarcher.product.dao.[1mProductDAOImplTest[m
[[1;34mINFO[m]
[[1;34mINFO[m] Results:
[[1;34mINFO[m]
[[1;34mINFO[m] [1;32mTests run: 1, Failures: 0, Errors: 0, Skipped: 0[m
命令行的 flag:
❯ mvn install -DskipTests
Eclipse 里的设置:

这里 user settings 不需要加值,默认会显示 m2 下面的配置文件
执行结果:
[[1;34mINFO[m] [1m--- [0;32mmaven-surefire-plugin:2.22.1:test[m [1m(default-test)[m @ [36mproductservices[0;1m ---[m
[[1;34mINFO[m] Tests are skipped.
此时的结构:
❯ tree productservices/src/main
productservices/src/main
└── java
└── com
└── goldenaarcher
└── product
├── bo
│ ├── ProductBO.java
│ └── ProductBOImpl.java
├── dao
│ ├── ProductDAO.java
│ └── ProductDAOImpl.java
└── dto
└── Product.java
8 directories, 5 files
代码实现:
ProductBO.java
package com.goldenaarcher.product.bo;
import com.goldenaarcher.product.dto.Product;
public interface ProductBO {
void create(Product product);
Product findProduct(int id);
}
ProductBOImpl.java
package com.goldenaarcher.product.bo;
import com.goldenaarcher.product.dao.ProductDAO;
import com.goldenaarcher.product.dao.ProductDAOImpl;
import com.goldenaarcher.product.dto.Product;
public class ProductBOImpl implements ProductBO {
private static ProductDAO dao = new ProductDAOImpl();
@Override
public void create(Product product) {
dao.create(product);
}
@Override
public Product findProduct(int id) {
return dao.read(id);
}
}
这里也不会过多的折腾配置……下次一定
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>6.0.11version>
dependency>