如果是初用Maven的小伙伴,就会觉得它和.NET中的Nuget很像,用来管理项目中的包依赖,毕竟Java依赖包浩如烟海,没个包管理器,简直是噩梦,当然Maven的作用不止如此,他提供了:
- 依赖管理:Maven的核心功能,让开发者可以通过pom.xml来管理项目所需的库和框架,就按照Nuget来理解就行;
- 项目构建:提供了一套完整的构建机制,可以自动完成项目的编译、测试、打包、部署等操作,功能类似于MSBuild,通过配置POM文件就可以轻松实现;
- 模块管理:Maven提供了多模块的管理,可以允许开发者在一个项目中包含多个子模块,类似于.NET中的解决方案和.csproj等功能的集合体;
- 标准化管理:Maven提供了标准化的项目结构,便于团队管理。
管他啥功能,别人都在用,我也用,用多了自然知道是干啥的了。
Maven配置
大家可以去官网上下载最新版本,我本地已经有了3.6.2的版本了,就不再额外安装了。
配置环境变量
- 在环境变量中添加“maven_home”,路径为maven的安装路径,本人的安装路径为
D:\DevSoft\maven_3.6.2
; - 在Path中添加
%maven_home%\bin\
,点击确认; - 打开命令行,输入
mvn -v
验证是否配置成功;
本地配置
打开maven目录,找到conf,打开settings.xml,找到localRepository
,不要用c盘,毕竟作为一名开发,c盘真的不富裕,把本地仓库位置挪走。
<localRepository>D:\\Repository\\Maven</localRepository>
由于某些原因,mvn更新包的速度会很慢,建议使用阿里云的镜像,一样是在settings.xml的mirrors节点下添加:
<!-- 阿里云仓库 -->
<mirros>
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<!-- 中央仓库1 -->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<!-- 中央仓库2 -->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
</mirros>
Idea设置
Idea中也要进行一些简单设置,在文件->设置->构建->Maven中,按自己的情况配置Maven地址和配置文件。
别上来就整mvn archetype:generate ***
之类的来创建项目,放着打火机不用,非要自己钻木取火,Idea:文件->新建->项目调出项目创建界面:
因为是maven项目,构建系统直接选择maven,JDK选择本地安装的1.8版本,这里的名称类似于.NET中的解决方案名称,不同的是,这个解决方案也可以是一个项目,高级设置中有一个组Id和工件Id,分别对应pom文件中的groupId和artifactId(这里我觉得没必要翻译,用中文反而差点意思),groupid一般就是公司网址的反写+项目名称,这里瞎写了一个:com.lmmplat.net2java
,artifactid你可以理解为是项目名,一般就是项目名+模块名,到这里,一个简单的Maven项目就创建完成了。
POM文件
上图中我们看到了项目中存在一个pom.xml
文件,pom是maven中核心文件,包含项目的基本信息,主要用于表述项目如何构建、声明依赖等:
<?xml version="1.0" encoding="UTF-8"?>
<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>com.lmmplat.net2java</groupId>
<artifactId>lmmplat</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
一个完整的pom文件至少包含一个project根和groupId、artifactId、version三个元素,groupId前文中也表述过,一般来说就是公司网址的反写+项目名称,最好是唯一的;artifactId是工程标识,通常就是项目名称+模块名称,比如llmplat-api、llmplat-core等;version就是工程的版本号。这个文件看起来简单,实际上是以为它默认继承了一个Super pom,maven使用Super pom加项目pom来执行,我们可以通过mvn help:effective-pom
来查看实际生效的pom。
POM详解
POM的全程为Project Object Model,是整个项目的描述未见,定义了项目构建、依赖管理以及其他相关的配置信息,学习Maven可以说就是学习如何配置POM,下面我会挑选最常用的一些内容进行讲解:
- 项目描述:
- groupId:组织的唯一标识,一般是公司域名反写+项目名
- artifactId:项目内的唯一表示,一般是项目名+模块名
- version:版本号,值得一提的是
1.0-SNAPSHOT
中的snapshot,这个一般表示该版本尚不稳定 - description:项目描述,当然还有name、url等属性,一般都是用来生成文档
- packaging:文件的打包类型,有pom、jar、war等,pom类型表示该项目是一个聚合项目或父项目,多用于组织和协调项目模块
- modelVersion:描述项目遵循哪一个pom模型
- properties:用于定义后续配置中用到的变量,多用于版本号的统一管理,如
<slf4j.version>1.7.36<slf4j.version>
,在后面的依赖管理中就可以统一用${slf4j.version}
来替代,便于版本的管理和统一 - parent:parent元素一般表示一个项目继承自另外一个maven项目,通常用于多模块的maven项目结构,好处是子模块可以继承父模块的配置,易于整个项目统一维护
<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>
<parent>
<groupId>com.lmmplat.net2java</groupId>
<artifactId>lmmplat</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>lmmplat-api</artifactId>
</project>
- 构建配置:
- build:定义项目如何构建
- plugins:定义要使用的插件
- 依赖管理:
- dependencies:项目依赖配置,指定项目所需的依赖
- dependencyManagement:集中管理多个模块的依赖,比如在父项目中统一指定依赖的版本号,子模块只需要引用依赖即可
- 模块管理:
- modules:主要针对多模块项目,指定包含的子模块,多是在父项目中使用
- 仓库管理:
- repositories:定义项目中使用的远程仓库地址
- pluginRepositories:定义项目中使用的插件仓库地址
- 配置管理
- profiles:为项目定义不同的构建环境或集合配置。
实际上Maven的功能不止如此,但对于大多数开发者来说,上面的功能已经足够使用了。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--描述项目遵循那个POM模型,必须,基本不需要懂-->
<modelVersion>4.0.0</modelVersion>
<!--组织的唯一标识,一般是公司域名反写+项目名-->
<groupId>com.lmmplat.net2java</groupId>
<!--项目内的唯一表示,一般是项目名+模块名-->
<artifactId>lmmplat</artifactId>
<!--版本号-->
<version>1.0-SNAPSHOT</version>
<!--项目的打包类型:pom、jar、war等-->
<packaging>pom</packaging>
<!--项目的详细描述-->
<description>这是一个示例项目</description>
<!--声明所依赖的外部库或组件-->
<dependencies>
<!--引入了slf4j的依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
<!--用于配置项目构建相关信息-->
<build>
<plugins>
<!--插件:下面这个插件能够将spring boot应用打包为可执行的jar或war文件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<mainClass>com.lmmplat.net2java.Main</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!--远程仓库配置-->
<repositories>
<!--比如有时候你需要用到自己搭建的私有仓库-->
<repository>
<id>central</id>
<name>lmmplat中央仓库</name>
<!--地址我瞎写的,lmm最近比较火-->
<url>https://repo.maven.lmmplat.cn/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<!--模块信息描述-->
<modules>
<!--子项目相对路径-->
<module>lmmplat-api</module>
</modules>
<!--自定义变量-->
<properties>
<!--自定义了一个名为sl4j.version的变量,用于后续替代sl4j的版本依赖-->
<slf4j.version>1.7.32</slf4j.version>
</properties>
</project>
Archetype
如果你用Idea新建项目可以发现一个MavenArchetype选项,这个就是Maven工程模板了,类似于VS新建项目里的项目模板,比如org.apache.maven.archetypes:maven-archetype-webapp
就可以对标一下VS里的ASP.NET Core Web应用
,可以帮助你快速构建应用,下面列一些比较常用的MavenArchetype,一般我都是直接通过maven-archetype-quickstart
创建项目,再通过修改pom来调整项目,比如我想创建一个Spring Boot项目,我们可以先创建一个quickstart项目,然后通过在pom.xml中添加Spring Boot依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.3</version>
</dependency>
<!-- 添加其他需要的Spring Boot Starters -->
</dependencies>
然后添加一个Application类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
一个Spring Boot项目就创建完成了。
生命周期
一个项目从构建到发布,Maven为期定义了一个完整的声明周期,点开Idea界面右侧边栏的m图标,就可以看见一个大概的生命周期:
阶段 | 操作 | 描述 |
---|---|---|
clean | 清理 | 通常在构建之前执行,用于删除target中的输出文件,从头开始,未必不是一件好事 |
validate | 验证 | 验证项目的正确性 |
compile | 编译 | 编译项目 |
test | 测试 | 运行单元测试 |
package | 打包 | 将编译后的文件打包成目标格式,如jar或war |
verify | 检查 | 检查集成测试的结果,保证质量达标 |
install | 安装 | 安装打包的项目到本地仓库,供其他项目使用 |
site | 站点 | 生成项目文档和站点信息mvn |
deploy | 部署 | 将打包好的项目报拷贝到远程仓库(我看就没有这个必要了吧) |
工作中比较常用的就是mvn clean
、mvn compile
、mvn package
、mvn install
几个命令,当我们进行操作是,只有该阶段及该阶段之前的命令会被调用,如我使用mvn install
,那clean->validate->compile->test->package->versify->install会执行,而之后不会被执行。当然mvn的生命周期的控制可以更为精细,但我们绝大多数的时候并不需要用到这些功能,如果需要,再去细化研究。