博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Maven详细教程
阅读量:7154 次
发布时间:2019-06-29

本文共 16508 字,大约阅读时间需要 55 分钟。

前言

本文可以帮助你加深对Maven的整体认识,不是一篇基础文章。如果你现在还没有用 Maven 跑过 HelloWorld,那么本文可能不适合你。

一、Maven简介

Maven 官网:

Maven 3.3.9版本文档:

Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

  1. 版本:maven有自己的版本定义和规则
  2. 构建:可以完成编译,打包,部署等。
  3. 依赖管理:方便引入所需依赖 Jar 包,不需手动下载
  4. 文档生成:maven的site命令支持各种文档信息的发布,包括构建过程的各种输出,javadoc,产品文档等。
  5. 项目关系:一个大型的项目通常有几个小项目或者模块组成,用maven可以很方便地管理

二、Maven生命周期

maven把项目的构建划分为不同的生命周期(lifecycle)。粗略一点的话,它这个过程(phase)包括:

  1. 验证(validate):验证项目是否正确
  2. 编译(compile): 编译项目的源代码
  3. 测试(test):使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署
  4. 打包(package)
  5. 验证(verify)
  6. 安装(install)
  7. 部署(deploy)

maven中所有的执行动作(goal)都需要指明自己在这个过程中的执行位置,然后maven执行的时候,就依照过程的发展依次调用这些goal进行各种处理。

这个也是maven的一个基本调度机制。一般来说,位置稍后的过程都会依赖于之前的过程。当然,maven同样提供了配置文件,可以依照用户要求,跳过某些阶段。

三、Maven 版本规范

maven使用如下几个要素来唯一定位某一个输出物: groupId:artifactId:packaging:version 。比如org.springframework:spring:2.5 。每个部分的解释如下:

  1. groupId 公司,团体等。如Apache Software的项目有以org.apache开头的groupId。
  2. artifactId 项目的唯一标识符。比如一个helloworld项目就叫helloworld。
  3. packaging 项目打包输出的类型,默认是jar。类型为war的项目产生一个web应用。
  4. version 一个项目的特定版本。发布的项目有一个固定的版本标识来指向该项目的某一个特定的版本。而正在开发中的项目可以用一个特殊的标识,这种标识给版本加上一个"SNAPSHOT"的标记。

    • maven有自己的版本规范,一般是如下定义 <major version>.<minor version>.<incremental version>-<qualifier> ,比如1.2.3-beta-01。要说明的是,maven自己判断版本的算法是major,minor,incremental部分用数字比较,qualifier部分用字符串比较,所以要小心 alpha-2和alpha-15的比较关系,最好用 alpha-02的格式。
    • maven在版本管理时候可以使用几个特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:

      • SNAPSHOT 如果一个版本包含字符串"SNAPSHOT",Maven就会在安装或发布这个组件的时候将该符号展开为一个日期和时间值,转换为UTC时间。例如,"1.0-SNAPSHOT"会在2010年5月5日下午2点10分发布时候变成1.0-20100505-141000-1。这个词只能用于开发过程中,因为一般来说,项目组都会频繁发布一些版本,最后实际发布的时候,会在这些snapshot版本中寻找一个稳定的,用于正式发布,比如1.4版本发布之前,就会有一系列的1.4-SNAPSHOT,而实际发布的1.4,也是从中拿出来的一个稳定版。
      • LATEST 指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
      • RELEASE 指最后一个发布版。

四、Maven插件机制

1. Maven默认插件

不配置Plugin时,Maven默认会使用以下插件。如果针对各个 plugin 有特殊配置的话,需要显示指定 plugin 和 属性配置。

plugin function life cycle phase
maven-clean-plugin 清理上一次执行创建的target文件 clean
maven-resources-plugin 处理资源文件 resources,testResources
maven-compiler-plugin 编译Java代码 compile、testCompile
maven-surefire-plugin 执行单元测试文件 test
maven-jar-plugin 创建 jar package
maven-install-plugin 拷贝jar到本地的maven仓库 .m2/repository 下面 install
maven-deploy-plugin 发布 jar deploy
maven-site-plugin 生成文档 site
maven-site-plugin:将工程所有文档生成网站,生成的网站界面默认和apache的项目站点类似,但是其文档用doxia格式写的,目前不支持docbook,需要用其他插件配合才能支持。需要指出的是,在maven 2.x系列中和maven3.x的site命令处理是不同的,在旧版本中,用 mvn site 命令可以生成reporting节点中的所有报表,但是在maven3中,reporting过时了,要把这些内容作为 maven-site-plugin的configuration的内容才行。详细内容可以参考
src/main/java
true
**/*.xml
src/main/resources
true
**/*.properties
*.xml
*.dic
*.txt
src/main/resources
false
*.p12
maven-compiler-plugin
3.1
1.8
1.8
UTF-8
org.apache.maven.plugins
maven-resources-plugin
2.6
UTF-8

2. Maven常用插件

2.0 spring-boot-maven-plugin

当使用SpringBoot开发项目的时候,会使用到spring-boot-maven-plugin插件

官方文档:

Spring Boot Maven plugin有5个Goals:

命令 说明
spring-boot:repackage 默认goal。在mvn package之后,再次打包可执行的jar/war,<br/>并将mvn package生成的软件包重命名为*.original
spring-boot:run 运行Spring Boot应用
spring-boot:start 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
spring-boot:stop 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
spring-boot:build-info 生成Actuator使用的构建信息文件build-info.properties

其中比较重要的命令是:

mvn package spring-boot:repackage

执行后会看到生成的两个jar文件,一个是*.jar,另一个是*.jar.original

这是由于在执行上述命令的过程中,Maven首先在package阶段打包生成*.jar文件;然后执行spring-boot:repackage重新打包

我们也可以跳过repackage阶段

clean deploy -D spring-boot.repackage.skip=true

加上-D spring-boot.repackage.skip=true参数即可,此时只会生成一个普通的jar包

2.1 Tomcat插件

tomcat插件有两种:tomcat-maven-plugin 和 tomcat7-maven-plugin,使用方式基本相同。

  • tomcat-maven-plugin 插件是org.codehaus.mojo组织提供的,里面的tomcat是6.0.29版本,没有更新了。
  • tomcat7-maven-plugin 插件是apache提供的,官网:
  1. tomcat7-maven-plugin 插件使用

    org.apache.tomcat.maven
    tomcat7-maven-plugin
    2.2
    /
    8080
    UTF-8
    tomcat7
    package
    run

    命令:

    tomcat7:deploy  --部署一个web war包tomcat7:reload  --重新加载web war包tomcat7:start    --启动tomcattomcat7:stop    --停止tomcattomcat7:undeploy --停止一个war包tomcat7:run --启动嵌入式tomcat ,并运行当前项目
  2. tomcat-maven-plugin 插件使用

    org.codehaus.mojo
    tomcat-maven-plugin
    1.1
    /helloworld
    8080
    UTF-8
    http://localhost:8080/manager/html
    tomcat6
    -Xms256m -Xmx512m -XX:MaxPermSize=512m

    命令:

    tomcat:deploy   --部署一个web war包tomcat:reload   --重新加载web war包tomcat:start    --启动tomcattomcat:stop    --停止tomcattomcat:undeploy --停止一个war包tomcat:run  --启动嵌入式tomcat ,并运行当前项目

配置参数:

path:是访问应用的路径
port:是tomcat 的端口号
uriEncoding:URL按UTF-8进行编码,这样就解决了中文参数乱码。
Server:指定tomcat名称。

2.2 自动部署插件wagon

自动部署包含三个步骤:

编译打包、上传到服务器、在服务器上执行linux命令

2.2.1 文件上传到服务器

Maven项目可使用 mvn install 指令打包,打包完成后包位于target目录下,要想在远程服务器上部署,首先要将包上传到服务器。

首先在本地的setting.xml中配置server的信息,包括id,用户名,密码。(当然也可以在pom.xml里面配置)

linux_server
user
password

pom.xml

org.apache.maven.wagon
wagon-ssh
2.8
org.codehaus.mojo
wagon-maven-plugin
1.0
linux_server
target/test.war
scp://user:password@192.168.20.128/home/tomcat7/webapps

<serverId>linux_server</serverId>: 在setting.xml中配置的server的id名字

<fromFile>target/test.war</fromFile>:是要上传到服务器的文件,一般来说是jar或者war包 <url>scp://user:password@192.168.20.128/home/tomcat7/webapps</url>:配置服务器的用户、密码、地址以及文件上传的目录

命令:

# 对项目进行打包和上传操作mvn clean install wagon:upload-single

如果觉的wagon命令太长,可以设置 excutions 来配置phase和goals来简化命令。

2.2.2 在服务器上执行linux命令

1. 运行jar文件
org.apache.maven.wagon
wagon-ssh
2.8
org.codehaus.mojo
wagon-maven-plugin
1.0
target/test.jar
scp://user:password@192.168.20.128/home/java/exe
pkill -f test.jar
nohup java -jar /home/java/exe/test.jar
true

命令

mvn clean install wagon:upload-single wagon:sshexec
2. 上传war包并启动Tomcat
org.apache.maven.wagon
wagon-ssh
2.8
org.codehaus.mojo
wagon-maven-plugin
1.0
target/javawebdeploy.war
scp://user:password@192.168.20.128/home/tomcat7/webapps
sh /home/tomcat7/bin/shutdown.sh
rm -rf /home/tomcat7/webapps/test
sh /home/tomcat7/bin/startup.sh
true

命令

mvn clean install wagon:upload-single wagon:sshexec

2.2.3 配置execution

如果觉得 mvn clean package wagon:upload-single wagon:sshexec 命令太长了不好记,那么可以配置execution,在运行deploy的同时运行upload-single和sshexec。

org.apache.maven.wagon
wagon-ssh
2.8
org.codehaus.mojo
wagon-maven-plugin
1.0
upload-deploy
deploy
upload-single
sshexec
target/test.war
scp://user:password@192.168.20.128/home/tomcat7/webapps
sh /home/tomcat7/bin/shutdown.sh
rm -rf /coder/tomcat7/webapps/test
sh /coder/tomcat7/bin/startup.sh
true

命令

mvn clean deploy

2.2.4. 完整示例配置

首先在本地的setting.xml中配置server的信息,包括id,用户名,密码。(当然也可以在pom.xml里面配置)

linux_server
user
password

pom.xml

org.apache.maven.wagon
wagon-ssh
2.8
org.codehaus.mojo
wagon-maven-plugin
1.0
linux_server
scp://user:password@192.168.20.128/home/tomcat7/webapps
true
upload-war-to-server
deploy
upload-single
sshexec
target/test.war
datefilename=$(date +%Y%m%d-%H%M%S);cp /home/tomcat7/webapps/test.war /home/tomcat7/webapps/test.war.$datefilename
ps -ef | grep /home/tomcat7/ | grep -v grep | awk {'print $2'} | sed -e "s/^/kill -9 /g" | sh
rm -rf /home/tomcat7/webapps/test
export JAVA_HOME=/home/jdk/jdk1.8.0_91;sh /home/tomcat7/bin/startup.sh

命令

mvn clean deploy

五、Maven 项目依赖

1. 多模块依赖和继承

项目结构图:

parent    ├─childA(model层)    │  └─pom.xml(jar)    ├─childB(web层)    │  └─pom.xml(war)    └─pom.xml(pom)
  1. parent中执行mvn install就能将 childA和childB 一起编译

    parent的pom.xml做如下配置:

    com.song
    parent
    1.0-SNAPSHOT
    pom
    childA
    childB

    childA和childB的pom.xml都需要配置parent,防止引入的包冲突(如果不加parent,会分别去编译他们引入的依赖,会重复引入包):

    parent
    com.song
    1.0-SNAPSHOT
    4.0.0
    childA
    jar
    parent
    com.song
    1.0-SNAPSHOT
    4.0.0
    childB
    war
  2. 子pom间存在引用关系,比如childB引用到了childA的jar包
com.module
childA
1.0-SNAPSHOT

2. 子项目继承父项目的依赖

parent中加上<dependencyManagement>,child项目就可以继承parent项目的依赖,并且在child中可以不用加version了。

javax.servlet
servlet-api
2.5

3. 依赖范围

如果不显示执行 <scope> 属性时,默认 <scope>compile</scope>

scope 属性包括:

  1. compile(编译范围):编译范围的<dependency>在所有的classpath中可用,同时它们也会被打包
  2. provided(已提供范围):表示部署的环境当中有某容器已经提供了该jar包,只在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的servlet容器(Tomcat)提供。
  3. runtime(运行时范围):只在运行和测试系统的时候需要,但在编译的时候不需要。
  4. test(测试范围):在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
  5. system (系统范围):该范围不推荐使用(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)
详细可参考:

六、Maven profiles切换测试环境和正式环境

dev
dev
true
release
release
beta
beta
helloworld
src/main/resources
config/
src/main/resources/config/${profiles.active}
.

id代表这个环境的唯一标识,在 mvn install -Pdev 来指定。

此properties定义了三个环境,分别是dev(开发环境)、beta(测试环境)、release(发布环境)
activeByDefault=true代表如果不指定某个固定id的profile,那么就使用这个环境

使用 mvn install -Pdev会将 id 为 dev 的 profile 中的<properties>定义的属性profiles.active自动替换${profiles.active}占位符的变量。最终build到classpath的资源文件由maven-resources-plugin来指定,为src/main/resources/config/dev文件下的所有文件。

七、Maven 变量

1. 内置属性

  • ${basedir} represents the directory containing pom.xml
  • **${version}** equivalent to ${project.version } or ${pom.version }

2. Pom/Project properties

所有pom中的元素都可以用 project. 前缀进行引用,以下是部分常用的

  • **${project.build.directory}** results in the path to your "target" dir, this is the same as ${pom.project.build.directory}
  • ${project.build.outputDirectory} results in the path to your "target/classes" dir
  • ${project.name} refers to the name of the project.
  • ${project.version} refers to the version of the project.
  • ${project.build.finalName} refers to the final name of the file created when the built project is packaged

3. 本地用户设定

所有用的的 settings.xml 中的设定都可以通过 settings. 前缀进行引用

  • ${settings.localRepository} refers to the path of the user's local repository.
  • ${maven.repo.local} also works for backward compatibility with maven1

4. 环境变量

系统的环境变量通过 env. 前缀引用

  • ${env.M2_HOME} returns the Maven2 installation path.
  • **${java.home}** specifies the path to the current JRE_HOME environment use with relative paths to get for example: <jvm>${java.home}../bin/java.exe</jvm>

5. java系统属性

所有JVM中定义的java系统属性.

6. pom.xml自定义变量

...
hellowolrld
...

则引用 ${project.build.finalName} 就会得到值 hellowolrld

7. parent 工程的变量

parent工程的pom.xml中的变量用前缀 ${project.parent} 引用. 上级工程的版本也可以这样引用: ${parent.version }.

参考文章:

转载地址:http://pgegl.baihongyu.com/

你可能感兴趣的文章
Bash基础特性 -- 卷一
查看>>
linux系统查看命令
查看>>
JAVA推荐网站
查看>>
我的友情链接
查看>>
HTML5从零开始构建HTML 5 Web页面
查看>>
centos新增网卡未见到
查看>>
实体机关闭后再启动,kvm中虚拟机无法启动的问题
查看>>
日期正则表达式
查看>>
Maven多模块设置保持JDK版本一致
查看>>
PHP5.2X 升级到PHP5.3.X之后注意事项
查看>>
oracle控制文件的一点研究
查看>>
Spring Boot log backed logstash
查看>>
酷派新机型只做3G是一种勇气
查看>>
yum 错误
查看>>
Linux命令之ls
查看>>
gcc --hash-style
查看>>
PHP 显示表格(需要输入数量)
查看>>
根据颜色值获取颜色常量名: ColorToIdent
查看>>
测试人员提高业务掌握度的方案
查看>>
Juniper总结(一)——路由器体系结构
查看>>