1、Maven介绍
注:改章节的内容主要粘贴自:Maven学习总结(一)——Maven入门。
Maven(这个单词来自于意第绪语(犹太语),意为知识的积累,最初在Jakata Turbine项目中用来简化构建过程)是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。
1.1 项目构建
项目构建过程包括【清理项目】→【编译项目】→【测试项目】→【生成测试报告】→【打包项目】→【部署项目】这几个步骤,这六个步骤就是一个项目的完整构建过程。
理想的项目构建是高度自动化,跨平台,可重用的组件,标准化的,使用maven就可以帮我们完成上述所说的项目构建过程。
1.2 依赖管理
依赖指的是jar包之间的相互依赖,比如我们搭建一个Struts2的开发框架时,光光有struts2-core-2.3.16.3.jar这个jar包是不行的,struts2-core-2.3.16.3.jar还依赖其它的jar包,依赖管理指的就是使用Maven来管理项目中使用到的jar包,Maven管理的方式就是“自动下载项目所需要的jar包,统一管理jar包之间的依赖关系”。
1.3 使用Maven的好处
Maven中使用约定,约定java源代码代码必须放在哪个目录下,编译好的java代码又必须放到哪个目录下,这些目录都有明确的约定。
Maven的每一个动作都拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程
只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮我们处理其他事情
使用Maven可以进行项目高度自动化构建,依赖管理(这是使用Maven最大的好处),仓库管理。
2、下载、安装和配置
这里采用的操作系统是MacOS。
到Apache Maven Project的官网(http://maven.apache.org/download.cgi),下载Maven的安装包(apache-maven-3.6.0-bin.tar.gz)。
将压缩包解压到某个目录下,这里放在/Users/chengxia/Developer/Java/tools/apache-maven-3.6.0
。
接下来,配置Maven相关的环境变量。打开.bash_profile
(vim ~/.bash_profile
),在该文件中添加如下行:
# Maven settings
export M2_HOME=/Users/chengxia/Developer/Java/tools/apache-maven-3.6.0
export PATH=$PATH:$M2_HOME/bin
保存该文件之后,执行:
source ~/.bash_profile
使上面的配置生效。然后在命令行中执行mvn -v
,如果得到如下输出证明安装和配置已经完成:
$ mvn -v
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-25T02:41:47+08:00)
Maven home: /Users/chengxia/Developer/Java/tools/apache-maven-3.6.0
Java version: 1.8.0_181, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.1", arch: "x86_64", family: "Mac"
$
3、Maven管理HelloWorld项目的编译和清理
用Maven管理的项目,一般来说有着约定俗成的目录结构,如下mvn_test_proj目录,是一个新建的最简单的Maven工程。下面列出了其目录结构,也标识了每个目录一般的用途:
$ tree mvn_test_proj/
mvn_test_proj/
├── pom.xml --用于标识该项目是一个Maven项目,在其中定义该项目相关的配置
├── src
│ └── main
│ ├── java --存放项目的.java文件
│ └── resources --存放项目资源文件,如spring, hibernate配置文件
├── target --项目输出位置
└── test
├── java --存放所有测试.java文件,如JUnit测试类
└── resources --存放项目资源文件,如spring, hibernate配置文件
在上面的java代码放置的目录中添加如下的Java源文件:
HelloWorld.java
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
然后,在mvn_test_proj目录下执行mvn compile
命令,如下:
$ mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.mvn.test.hello:helloworld-first >-----------------
[INFO] Building helloworld-first SNAPSHOT-0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.6/maven-resources-plugin-2.6.pom
... ...
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-container-default/1.5.5/plexus-container-default-1.5.5.jar (217 kB at 5.8 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/collections/google-collections/1.0/google-collections-1.0.jar (640 kB at 7.5 kB/s)
[INFO] No sources to compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:46 min
[INFO] Finished at: 2019-02-28T23:14:35+08:00
[INFO] ------------------------------------------------------------------------
可以看出在编译的时候,mvn会自动去下载相关的依赖,这个过程耗时比较长。最后,编译的结果是No sources to compile
。
检查了一下,忘记配置pom.xml文件了。在上面目录中的pom.xml文件中输入如下内容:
<?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">
<!--所有的Maven项目都必须配置这四个配置项-->
<modelVersion>4.0.0</modelVersion>
<!-- groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。 -->
<!--groupId指的是项目名的项目组,命名规范和包名一样-->
<groupId>com.mvn.test.hello</groupId>
<!--artifactId指的是项目中的某一个模块,默认命名方式是"项目名-模块名"-->
<artifactId>helloworld-first</artifactId>
<!--version指的是版本,这里使用的是Maven的快照版本-->
<version>SNAPSHOT-0.0.1</version>
</project>
groupid和artifactId说明,引用自链接maven中的groupId和artifactId到底指的是什么?:
groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。
groupId一般分为多个段,这里我只说两段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。
比如我创建一个项目,我一般会将groupId设置为cn.snowin,cn表示域为中国,snowin是我个人姓名缩写,artifactId设置为testProj,表示你这个项目的名称是testProj,依照这个设置,你的包结构最好是cn.snowin.testProj打头的,如果有个StudentDao,它的全路径就是cn.snowin.testProj.dao.StudentDao。
然后,再执行如下命令,可以发现编译成功,如下:
$ mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.mvn.test.hello:helloworld-first >-----------------
[INFO] Building helloworld-first SNAPSHOT-0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld-first ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld-first ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/chengxia/Developer/Java/mvn_test_proj/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.411 s
[INFO] Finished at: 2019-02-28T23:20:08+08:00
[INFO] ------------------------------------------------------------------------
$ tree ../mvn_test_proj/
../mvn_test_proj/
├── pom.xml
├── src
│ └── main
│ ├── java
│ │ └── HelloWorld.java
│ └── resources
├── target
│ ├── classes
│ │ └── HelloWorld.class --可以看到该目录下生成了class文件
│ └── maven-status
│ └── maven-compiler-plugin
│ └── compile
│ └── default-compile
│ ├── createdFiles.lst
│ └── inputFiles.lst
└── test
├── java
└── resources
执行mvn clean
可以完成清理操作。这个过程中,maven也会自动下载相关的依赖。清理之后,target目录直接被删除。再次编译,target目录又会再次被生成(只有第一次编译会去下载所需的依赖,第一次下载完成之后,后面可以直接用,不用再次下载)。如下:
$ mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.mvn.test.hello:helloworld-first >-----------------
[INFO] Building helloworld-first SNAPSHOT-0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom (3.9 kB at 1.1 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom (13 kB at 11 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.jar (25 kB at 21 kB/s)
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ helloworld-first ---
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.pom (4.1 kB at 3.7 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/16/spice-parent-16.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/spice/spice-parent/16/spice-parent-16.pom (8.4 kB at 3.7 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/5/forge-parent-5.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/sonatype/forge/forge-parent/5/forge-parent-5.pom (8.4 kB at 6.9 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar (226 kB at 50 kB/s)
[INFO] Deleting /Users/chengxia/Developer/Java/mvn_test_proj/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.987 s
[INFO] Finished at: 2019-02-28T23:53:24+08:00
[INFO] ------------------------------------------------------------------------
$ tree ../mvn_test_proj/
../mvn_test_proj/
├── pom.xml
├── src
│ └── main
│ ├── java
│ │ └── HelloWorld.java
│ └── resources
└── test
├── java
└── resources
7 directories, 2 files
$ mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.mvn.test.hello:helloworld-first >-----------------
[INFO] Building helloworld-first SNAPSHOT-0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld-first ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld-first ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/chengxia/Developer/Java/mvn_test_proj/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.420 s
[INFO] Finished at: 2019-02-28T23:55:31+08:00
[INFO] ------------------------------------------------------------------------
$ tree ../mvn_test_proj/
../mvn_test_proj/
├── pom.xml
├── src
│ └── main
│ ├── java
│ │ └── HelloWorld.java
│ └── resources
├── target
│ ├── classes
│ │ └── HelloWorld.class
│ └── maven-status
│ └── maven-compiler-plugin
│ └── compile
│ └── default-compile
│ ├── createdFiles.lst
│ └── inputFiles.lst
└── test
├── java
└── resources
13 directories, 5 files
$
4、Maven中修改依赖的下载目录
上面在使用maven的过程中,自动下载了好多依赖,这些依赖存放在什么目录下面呢?从$MAVEN_HOME/conf/settings.xml
文件中,找到如下配置:
<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
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
可以看出,这项配置默认是注掉的,也就是说默认依赖的下载目录是用户home目录下的.m2/repository
目录,可以通过修改该配置项改动依赖的下载位置,这里改成如下:
<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
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
-->
<localRepository>/Users/chengxia/Developer/Java/tools/apache-maven-3.6.0/repository</localRepository>
然后,通过如下命令将原依赖存放目录中的内容移动到该目录下:
$ cd ~/Developer/Java/tools/apache-maven-3.6.0/
$ mv ~/.m2/repository/ .
$ ls
LICENSE README.txt boot lib
NOTICE bin conf repository
$
操作完成之后,依然可以正常编译和清理,无需重新下载所需依赖。如下:
$ mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.mvn.test.hello:helloworld-first >-----------------
[INFO] Building helloworld-first SNAPSHOT-0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld-first ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld-first ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/chengxia/Developer/Java/mvn_test_proj/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.400 s
[INFO] Finished at: 2019-03-01T00:24:48+08:00
[INFO] ------------------------------------------------------------------------
$