简单的说就是 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>