概述
Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven作为一个构建工具,不仅能帮我们自动化构建,还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具。
Maven不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了中央仓库,能帮我们自动下载其他构件。
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目。
Maven的安装
这里仅说明windows下maven的安装,在安装前请确认JDK已安装完毕。
1.到官网上下载最新版本的maven
2.下载后的文件直接解压就行
3.配置环境变量
4.打开setting.xml,配置本地仓库和镜像
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!--更改了本地仓库位置-->
<localRepository>M:\\soft\\maven\\repository</localRepository>
<mirrors>
<!--配置了中央仓库的镜像:(换成了阿里的,比较稳定)-->
<mirror>
<id>nexus-aliyun</id>
<name>nexus-aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<proxies>
<proxy>
<id>my-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>IP地址</host>
<port>端口号</port>
<!--
<username>***</username>
<password>***</password>
<nonProxyHosts>
repository.mycom.com|*.google.com
</nonProxyHosts>
-->
</proxy>
</proxies>
</settings>
Maven目录结构
- bin目录:
该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。
- boot目录:
该目录只包含一个文件,该文件为plexus-classworlds-2.5.2.jar。plexus-classworlds是一个类加载器框架,相对于默认的java类加载器,它提供了更加丰富的语法以方便配置,Maven使用该框架加载自己的类库。
- conf目录:
该目录包含了一个非常重要的文件settings.xml。直接修改该文件,就能在机器上全局地定制Maven的行为,一般情况下,我们可以直接复制该文件至~/.m2/目录下(~表示用户目录),然后修改该文件,在用户范围定制Maven的行为。
- lib目录:
该目录包含了所有Maven运行时需要的Java类库,Maven本身是分模块开发的,因此用户能看到诸如maven-core-3.0.jar、maven-model-3.0.jar之类的文件,此外这里还包含一些Maven用到的第三方依赖如commons-cli-1.2.jar、commons-lang-2.6.jar等等。
Maven的常用命令
- mvn archetype:项目名: 创建Maven项目
- mvn clean:表示运行清理操作(会默认把target文件夹中的数据清理)。
- mvn compile:编译源代码
- mvn clean compile:表示先运行清理之后运行编译,会将代码编译到target文件夹中。
- mvn clean test:运行清理和测试。
- mvn clean package:运行清理和打包。
- mvn clean install:运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用。
- mvn clean deploy:运行清理和发布(发布到私服上面)。
- mvn deploy:发布项目
- mvn test-compile: 编译测试源代码
- mvn test: 运行应用程序中的单元测试
- mvn site:生成项目相关信息的网站
- mvn package: 根据项目生成的jar
- mvn install: 在本地Repository中安装jar
Idea中配置Maven
我们目前使用较多的是Idea来开发Java项目,Eclipse请自行下来百度。
注意:设置和为新项目设置都需配置。
pom.xml详解
POM是项目对象模型(Project Object Model)的简称,它是Maven项目中的文件,使用XML表示,名称叫做pom.xml。作用类似ant的build.xml文件,功能更强大。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。事实上,在Maven世界中,project可以什么都没有,甚至没有代码,但是必须包含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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 基本设置 The Basics -->
<!--组织标识,定义了项目属于哪个组,风向标,坐标,比如谷歌公司的myapp项目,就取名为 com.google.myapp-->
<groupId>com.dailyblue.java</groupId>
<!--项目名称也可以说你所模块名称,定义当面Maven项目在组中唯一的ID-->
<artifactId>guanwei</artifactId>
<!--
指定了项目当前的版本0.0.1-SNAPSHOT
SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的
alpha、beta为测试版本,测试版本一般会分为内部测试 alpha版、外部测试 beta版
rc、final、stable、release、GA稳定版(正式版)很多都不一样,但是大概就这几种。大部分正式版是啥也不带,就一个单纯的版本号,比如1.0、1.7.1等
-->
<version>1.0.1-SNAPSHOT</version>
<!-- 打包的格式,可以为:pom , jar , maven-plugin , ejb , war , ear , rar , par -->
<packaging>war</packaging>
<!-- 元素声明了一个对用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个POM声明name,以方便信息交流-->
<name>guanwei</name>
<!--需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。-->
<parent>
<groupId>com.dailyblue.java</groupId>
<artifactId>parentProjectName</artifactId>
<version>1.0-SNAPSHOT</version>
<!--如果父项目的pom.xml和子项目不在一个目录,需要在这里指定父项目的pom.xml路径-->
<relativePath>../otherProjectName/pom.xml</relativePath>
</parent>
<!--聚合关系:用于将多个maven项目聚合为一个大的项目。里边包含子项目的名称-->
<modules>
<module>childA</module>
<module>childB</module>
......
</modules>
<!--
项目之间的依赖是通过pom.xml文件里面的dependencies元素内的dependency元素进行的。
一个dependency元素定义一个依赖关系。
在dependency元素中我们主要通过依赖项目的groupId、artifactId和version来定义所依赖的项目。
-->
<dependencies>
<!--
groupId, artifactId, version:描述了依赖的项目唯一标志。
type:对应于依赖项目的packaging类型,默认是jar。
scope:用于限制相应的依赖范围、传播范围。
test:在测试范围有效,它在执行命令test的时候才执行,并且它不会传播给其他模块进行引入,比如 junit,dbunit 等测试框架。 compile:默认值,表示所有的情况都是有用的,包括编译和运行时。而且它的依赖性是可以传递的。
runtime:在程序运行的时候依赖,在编译的时候不依赖。 provided:跟compile类似,但它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。 system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径。
optional:让其他项目知道,当您使用此项目时,您不需要这种依赖性才能正常工作。
exclusions:包含一个或多个排除元素,每个排除元素都包含一个表示要排除的依赖关系的 groupId 和 artifactId。
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.dailyblue.java</groupId>
<artifactId>projectA</artifactId>
</exclusion>
......
</exclusions>
</dependency>
</dependencies>
<!--
dependencyManagement是表示依赖 jar 包的声明。即你在项目中的 dependencyManagement下声明了依赖,maven不会加载该依赖,dependencyManagement 声明可以被子POM 继承。
dependencyManagement的一个使用案例是当有父子项目的时候,父项目中可以利用 dependencyManagement 声明子项目中需要用到的依赖 jar 包,之后,当某个或者某几个子项目需要加载该依赖的时候,就可以在子项目中 dependencies 节点只配置 groupId 和 artifactId 就可以完成依赖的引用。
dependencyManagement主要是为了统一管理依赖包的版本,确保所有子项目使用的版本一致,类似的还有plugins和pluginManagement。
-->
<dependencyManagement>...</dependencyManagement>
<!--属性列表。定义的属性可以在 pom.xml 文件中任意处使用。使用方式为 ${property} -->
<properties>
<maven.compiler.source>1.8<maven.compiler.source>
<maven.compiler.target>1.8<maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<!-- 构建过程的设置 Build Settings -->
<build>
<!--
defaultGoal:默认执行目标或阶段。如果给出了一个目标,它应该被定义为它在命令行中(如 jar:jar)。如果定义了一个阶段(如安装),也是如此。
directory:构建时的输出路径。默认为:${basedir}/target 。
finalName:这是项目的最终构建名称(不包括文件扩展名,例如:guanwei-project-1.0.jar)
filter:定义 * .properties 文件,其中包含适用于接受其设置的资源的属性列表。换句话说,过滤器文件中定义的“name = value”对在代码中替换\$ {name}字符串。
-->
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
<!--资源的配置。资源文件通常不是代码,不需要编译,而是在项目需要捆绑使用的内容。-->
<resources>
<!--resources: 资源元素的列表,每个资源元素描述与此项目关联的文件和何处包含文件。-->
<resource>
<!--
targetPath:指定从构建中放置资源集的目录结构。目标路径默认为基本目录。将要包装在 jar 中的资源的通常指定的目标路径是 META-INF。
filtering:true|false。表示是否要为此资源启用过滤。请注意,该过滤器*.properties文件不必定义为进行过滤 - 资源还可以使用默认情况下在 POM 中定义的属性(例如\$ {project.version}),并将其传递到命令行中“-D”标志(例如,“-Dname = value”)或由 properties 元素显式定义。
directory:值定义了资源的路径。构建的默认目录是${basedir}/src/main/resources。
includes:一组文件匹配模式,指定目录中要包括的文件,使用*作为通配符。
excludes:指定目录中要排除的文件,使用*作为通配符。注意:如果include和exclude发生冲突,maven会以exclude作为有效项。
-->
<targetPath>META-INF/guanwei</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/guanwei</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<!--与resources功能类似,区别仅在于:testResources指定的资源仅用于test阶段,并且其默认资源目录为:${basedir}/src/test/resources。-->
<testResources>
...
</testResources>
<!--插件-->
<plugins>
<plugin>
<!--
groupId, artifactId, version:和基本配置中的 groupId、artifactId、version 意义相同。
extensions:值为 true 或 false。是否加载此插件的扩展名。默认为 false。
inherited:值为 true 或 false。这个插件配置是否应该适用于继承自这个插件的 POM。默认值为 true。
configuration:这是针对个人插件的配置,这里不扩散讲解。
dependencies:这里的 dependencies 是插件本身所需要的依赖。
executions:执行配置插件的目标的执行。
-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
...
</build>
<reporting>...</reporting>
<!-- 项目信息设置 More Project Information -->
<!--
项目信息相关的这部分标签都不是必要的,也就是说完全可以不填写。
它的作用仅限于描述项目的详细信息。
-->
<!--项目名-->
<name>maven-notes</name>
<!--项目描述-->
<description>maven 学习笔记</description>
<!--项目url-->
<url>https://gitee.com/dailyblue</url>
<!--项目开发年份-->
<inceptionYear>2022</inceptionYear>
<!--开源协议-->
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<!--组织信息(如公司、开源组织等)-->
<organization>
<name>...</name>
<url>...</url>
</organization>
<!--开发者列表-->
<developers>
<developer>
<id>dailyblue</id>
<name>GuanWei</name>
<email>dailyblue@vip.qq.com</email>
<url>https://gitee.com/dailyblue</url>
<organization>...</organization>
<organizationUrl>...</organizationUrl>
<roles>
<role>architect</role>
<role>developer</role>
</roles>
<timezone>+8</timezone>
<properties>...</properties>
</developer>
</developers>
<!--代码贡献者列表-->
<contributors>
<contributor>
<!--标签内容和<developer>相同-->
</contributor>
</contributors>
<!-- 环境设置 Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<!--配置远程仓库-->
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
仓库
在Maven世界中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。得益于坐标机制,任何Maven项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库。
实际的Maven项目将不再各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候,Maven会自动根据坐标找到仓库中的构件,并使用它们。
为了实现重用,项目构建完毕后可生成的构件也可以安装或者部署到仓库中,供其他项目使用。
仓库的坐标
任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。
该路经与坐标对应关系为groupId、artifactId、version、packaging等。
比如下面这个mysql依赖如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
对应的仓库的路径就是这样:
仓库的分类
本地仓库
一般来说,在Maven项目目录下,没有诸如lib这样用来存放依赖文件的目录。当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下,不管在Window还是Linux下,每个用户在自己用户目录下都有一个路径名为.m2/repository/的仓库目录。
如果你想自定义本地仓库目录地址。你可以编辑settings.xml文件,设置localRepository元素的值为具体的仓库地址,例如:
<!--更改了本地仓库位置-->
<localRepository>M:\\soft\\maven\\repository</localRepository>
远程仓库
中央仓库
由于最原始的本地仓库是空的,Maven必须知道至少一个可用的远程仓库,才能在执行Maven命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库,Maven的安装文件自带了中央仓库的配置。
中央仓库包含了这个世界上绝大多数流行的开源Java构件,以及源码、作者信息、SCM,信息、许可证信息等,每个月这里都会接受全世界Java程序员大概1亿次的访问,它对全世界Java开发者的贡献由此可见一斑。
配置远程中央仓库
在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他远程仓库中有,如JBoss Maven仓库。这时,可以在pom.xml中配置该仓库,代码如下:
<!-- 配置远程仓库 -->
<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>http://repository.jboss.com/maven2/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
<layout>default</layout>
</repository>
</repositories>
远程中央仓库认证
大部分的远程仓库不需要认证,但是如果是自己内部使用,为了安全起见,还是要配置认证信息的。
配置认证信息和配置远程仓库不同,远程仓库可以直接在pom.xml中配置,但是认证信息必须配置在settings.xml文件中。这是因为pom往往是被提交到代码仓库中供所有成员访问的,而settings.xml一般只存在于本机。因此,在settings.xml中配置认证信息更为安全。
<settings>
<!--配置远程仓库认证信息-->
<servers>
<server>
<id>releases</id>
<username>guanwei</username>
<password>dailyblue</password>
</server>
</servers>
</settings>
远程镜像
用过Maven的都知道,国外的中央仓库用起来太慢了,所以选择一个国内的镜像就很有必要,我推荐国内的阿里云镜像。 阿里云镜像:配置很简单,修改conf文件夹下的settings.xml文件,添加如下镜像配置:
<!--配置了中央仓库的镜像:(换成了阿里的,比较稳定)-->
<mirror>
<id>nexus-aliyun</id>
<name>nexus-aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<!--central,表示该配置为中央库的镜像,任何对于中央仓库的请求都会转至该镜像-->
<mirrorOf>central</mirrorOf>
</mirror>
部署构建(项目)到远程仓库
我们自己搭建远程仓库的目的就是为了可以方便部署我们自己项目的构件以及一些无法从外部仓库直接获取的构件。这样才能在开发时,供其他对团队成员使用。
Maven除了能对项目进行编译、测试、打包之外,还能将项目生成的构件部署到远程仓库中。
首先,需要编辑项目的pom.xml文件。配置distributionManagement元素,代码如下:
<distributionManagement>
<!--repository表示发布版本(稳定版本)的仓库-->
<repository>
<!--id为远程仓库的唯一标识。-->
<id>releases</id>
<!--name是为了方便人阅读。-->
<name>public</name>
<!--url表示该仓库的地址。-->
<url>远程仓库URL</url>
</repository>
<!--snapshotRepository表示快照版本(开发测试版本)的仓库-->
<snapshotRepository>
<id>snapshots</id>
<name>Snapshots</name>
<url>远程仓库URL</url>
</snapshotRepository>
</distributionManagement>
配置好了就运行命令mvn clean deploy,Maven就会将项目构建输出的构件部署到配置对应的远程仓库,如果项目当前的版本是快照版本,则部署到快照版本的仓库地址,否则就部署到发布版本的仓库地址。
仓库服务搜索
- MVNrepository:https://mvnrepository.com/
- 阿里云仓库:https://maven.aliyun.com/
私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。因此,一些无法从外部仓库下载到的构件也能从本地上传到私服上供大家使用。
私服的好处:
- 节省自己的外网速度
- 加速Maven构建
- 部署第三方构建
- 提高稳定性,增强控制
- 降低中央仓库的负荷
Idea下创建maven项目
1.新建项目
2.选择创建maven项目
3.输入groupid、ariId,选择项目路径
Maven项目目录结构
目录说明