《Maven实战》笔记
maven是什么
maven是
- 构建工具
- 依赖关系工具
- 项目信息管理工具
而JAVA世界的ant只是一个构建工具,不具备依赖管理的功能,需要配合使用ivy进行依赖管理。
maven的安装
下载maven,配置环境变量。
升级的技巧:使用符号链接,环境变量指向符号链接,升级的时候修改符号链接即可。
maven使用入门
手动搭建maven项目
- 编写pom
- 编写主代码和测试代码
使用ArcheType创建maven项目骨架
命令如下mvn archetype:generate
实际上上述命令的完整格式是:mvn groupId:artifactId:version:goal
即运行的是archetype插件的generate目标。
也可以为自己的项目开发archetype。
编译,测试,打包,安装,运行
- 编译:
mvn clean compile - 测试:
mvn clean test - 打包:
mvn clean package - 安装:
mvn clean install - 运行
- 使用maven-shade-plugin插件生成可执行的jar.
- pom中配置shade插件。
- 执行
mvn clean install,重新生成jar包。
- 运行jar包。
java -jar xxx.jar
- 使用maven-shade-plugin插件生成可执行的jar.
坐标和依赖
maven坐标的各个元素
- groupId
- artifactId
- version
- packaging:打包方式。比如jar或者war。
- classifier:附属构件。比如javadoc和源代码。
依赖的元素
- groupId
- artifactId
- version
- type:同坐标中的packaging。默认为jar。
- scope:依赖范围
- optional
- exclusions
依赖范围
三种classpath:编译classpath,测试classpath,运行classpath。
- compile:对编译、测试、运行三种classpath都有效。
- test:只对测试classpath有效。比如JUnit。
- provided:编译和测试classpath有效,运行classpath无效。比如servlet API。
- runtime:测试和运行classpath有效,编译classpath无效。比如JDBC驱动实现。
- system:与provided一致。只是这种情况必须显示指定依赖文件的路径,这样就和本机系统绑定了,使得构建不具有移植性,慎用。
- import:不会对三种classpath产生影响。
依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。
传递性依赖
传递性依赖机制:maven会解析各个直接依赖的pom,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。(我们只需要关心项目的直接依赖)
maven会自动解析所有项目的直接依赖和传递性依赖,确保每个构件只有唯一的版本在依赖中存在。最后解析后的这些依赖被称为已解析依赖。
相关命令
查看已解析依赖:mvn dependency:list
依赖树:mvn dependency:tree
分析依赖:mvn dependency:analyze
生命周期和插件
生命周期和阶段
maven对构建过程进行了抽象,被称为生命周期。生命周期本身不做具体任务,实际的任务由插件完成。这是一种模板方法模式。
生命周期包含一些阶段(phase),这些阶段有前后依赖关系,后面的阶段依赖前面的阶段。可以定义多个生命周期,生命周期之间彼此是独立的,不存在依赖关系。
Maven拥有三套独立的生命周期,分别是clean、default和site。
- clean生命周期的目的是清理项目。
- default生命周期的目的是构建项目。
- site生命周期的目的是建立项目站点。
clean生命周期
包含三个阶段:
- pre-clean
- clean
- post-clean
defalut生命周期
包含的阶段太多,详情 Introduction to the Build Lifecycle。
site生命周期
- pre-site
- site
- post-site
- site-deploy
命令行与生命周期的关系
常用的mvn clean compile命令实际上调用的是clean生命周期的clean阶段和default生命周期的compile阶段。
插件和插件目标
对于插件而言,为了能够复用代码,它能够执行多个任务,实现多个功能,这些功能聚集在一个插件里,每个功能就是一个插件目标。比如maven-dependency-plugin插件,它可以分析项目依赖,列出项目的依赖树,找出无用依赖。
通常写法是:插件:插件目标。
插件绑定
将生命周期中的阶段和插件目标绑定。
那么在命令行输入生命周期的阶段,则对应的插件目标就会执行相应的任务。
Q:是否可以直接在命令行中直接指定执行某个插件目标'???
A:可以。
多个插件目标可以绑定到同一个阶段。
总结
A Build Lifecycle is Made Up of Phases
A Build Phase is Made Up of Plugin Goals
聚合和继承
聚合
解决如下需求:想要用一条命令一次性构建多个项目(模块)。
这就是maven聚合(多模块)特性。
方法:增加一个聚合模块,其中的pom.xml中的packaging为pom。
聚合模块和其他模块的目录关系
不一定是父子关系,也可以是平行的目录结构。
继承
目的:解决多模块maven项目的配置重复问题。
方法:增加一个父模块,在父pom中声明一些配置供子pom继承。
父模块和聚合模块一般同时存在多模块maven项目中。父模块也要在聚合模块中的modules标签中配置。
可继承的pom元素
- groupId
- version
- dependencies
- dependencyManagement
- build
- repositories
- properties
- ...
依赖管理
可以将一些依赖放到父模块的dependencies元素中,这样子类就无需配置了。但会存在一个问题:所有的子模块都会依赖父模块dependencies元素中声明的依赖,即使一些子模块并不需要这些依赖。
解决方法:
在父模块中使用dependencyManagement元素声明依赖,这些依赖不为直接被子模块继承。子模块若要继承父模块dependencyManagement中声明的某个依赖的话,则需要在子模块中的dependencies元素中重新声明(只需要配置groupId和artifactId即可)。
虽然这种方式不会大幅度的减少配置,但是由于在父模块的pom中统一申明了依赖的版本,可以避免在子模块中使用的依赖版本不一致的情况。
import依赖范围
名为import的依赖范围只在dependencyManagement元素下采用效果。其作用是将目标pom中的dependencyManagement配置导入并合并到当前pom中的dependencyManagement元素中。
插件管理
pluginManagement和dependencyManagement类似。
聚合与继承的关系
目的不同:
- 聚合是为了方便快速构建项目。
- 继承是为了消除重复配置。
聚合模块 vs. 被聚合模块:聚合模块知道被聚合模块,但被聚合模块不知道聚合模块的存在。
父模块 vs. 子模块:父模块不知道那些子模块继承自它,但子模块都知道自己的父模块。
相同点:父模块和聚合模块都没有实际内容,并且两者的pom中的packaging都必须是pom。
实际项目中,会发现一个pom既是父pom,又是聚合pom,这么做主要是为了方便。
约定优于配置
所有的pom都继承自超级POM。
对于Maven3,超级POM在$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。
对于Maven2,超级POM在$MAVEN_HOME/lib/maven-model-x.x.x-uber.jar中的org/apache/maven/pom-4.0.0.xml路径下。
在超级POM中已经定义了源代码的路径、构建的输出路径等信息。
反应堆
构建一个多模块项目时,由于模块间存在继承或者聚合关系,模块间的构建是有先后关系的,整体构成一个有向无环图DAG。反应堆就是所有模块组成的一个构建结构。
持续集成
比如TensorFlow的持续集成:http://ci.tensorflow.org/
使用maven构建web应用
war文件的目录结构
todo
web项目的maven目录结构
todo
快速生成web项目的maven目录结构
jetty-maven-plugin插件
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.13.v20130916</version>
<configuration>
<webApp>
<contextPath>/</contextPath>
</webApp>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8081</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin
使用cargo实现自动化部署
Cargo支持两种本地部署的方式:standalone模式和existing模式。如下是standalone模式:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.6.2</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<home>D:\Program Files\apache-tomcat-8.0.23</home>
</container>
<configuration>
<type>standalone</type>
<home>${project.build.directory}/tomcat8x</home>
<properties>
<cargo.servlet.port>8181</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
existing模式:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.6.2</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<home>D:\Program Files\apache-tomcat-8.0.23</home>
</container>
<configuration>
<type>existing</type>
<home>D:\Program Files\apache-tomcat-8.0.23</home>
<!-- existing模式下好像无法更改端口 -->
<!--<properties>-->
<!--<cargo.servlet.port>8080</cargo.servlet.port>-->
<!--</properties>-->
</configuration>
</configuration>
</plugin>
Archetype
Archetype Catalog
- internal:maven-archetype-plugin内置的Archetype Catalog。
- local:~/.m2/archetype-catalog.xml
- remote:http://repo1.maven.org/maven2/archetype-catalog.xml https://repo.maven.apache.org/maven2/archetype-catalog.xml
- file://...:本机任何位置上的archetype-catalog.xml文件。
- http://...:使用http协议指定远程的archetype-catalog.xml文件。
mvn archetype:generate卡住的问题
原因:
执行命令mvn archetype:generate时,maven-archetype-plugin插件会先寻找archetype-catalog.xml文件,默认是从中央库中寻找该文件。由于中央库访问比较慢,所以出现卡顿现象。
解决方案:
方案(1):加上archetypeCatalog参数
mvn archetype:generate -DarchetypeCatalog=internal方案(2):配置一个国内的镜像,加速对archetype-catalog.xml的访问。比如阿里云的maven镜像,如下:
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
经验:安装maven后一定要配置一个国内的中央库镜像,比如阿里maven中央镜像库。因为后续很多mvn命令需要下载很多插件和依赖,网络不好容易导致操作失败。
下载单个构建的源码和文档
mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:sources
mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:javadoc
《Maven实战》笔记的更多相关文章
- HTML+CSS笔记 CSS笔记集合
HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...
- CSS笔记--选择器
CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...
- HTML+CSS笔记 CSS中级 一些小技巧
水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...
- HTML+CSS笔记 CSS中级 颜色&长度值
颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...
- HTML+CSS笔记 CSS中级 缩写入门
盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...
- HTML+CSS笔记 CSS进阶再续
CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...
- HTML+CSS笔记 CSS进阶续集
元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...
- HTML+CSS笔记 CSS进阶
文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...
- HTML+CSS笔记 CSS入门续集
继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...
- HTML+CSS笔记 CSS入门
简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...
随机推荐
- [转帖]GitHub上整理的一些工具
GitHub上整理的一些工具 技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 inf ...
- python中常用的九种数据预处理方法分享
Spyder Ctrl + 4/5: 块注释/块反注释 本文总结的是我们大家在python中常见的数据预处理方法,以下通过sklearn的preprocessing模块来介绍; 1. 标准化(St ...
- select、poll、epoll之间的区别总结[整理]【转】
转自:http://www.cnblogs.com/Anker/p/3265058.html select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符 ...
- html 塊 div span
塊級元素:元素結束后,另起一行:如p,table,h1,ul,ol 內聯元素:元素結束后,不會另起一行:如a,td.image.b <div>是塊級元素,div本身沒有含義,div是htm ...
- hbase中文内容编码转换
/** * HBASE中文转换 */ @Test public void testHbaseStr() throws Exception { // Hbase UTF8编码 String conten ...
- Linux 编译命令参数
基本格式:gcc [options] file1 file2... //若不加入参数,则按默认参数依次执行编译.汇编和链接操作,生成的可执行文件名为 a.out 常用参数:-E //只执行预处理操作 ...
- Django-website 程序案例系列-14 缓存的应用配置文件的写法
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5 ...
- Catenyms POJ - 2337(单词+字典序输出路径)
题意: 就是给出几个单词 看能否组成欧拉回路或路径 当然还是让输出组成的最小字典序的路 解析: 还是把首尾字母看成点 把单词看成边 记录边就好了 这题让我对fleury输出最小字典序又加深了一些 ...
- 自学Zabbix9.2 zabbix网络发现规则配置详解+实战
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix9.2 zabbix网络发现规则配置详解+实战 1. 创建网络发现规则 Conf ...
- 【BZOJ2484】[SDOI2011]打地鼠(暴力)
[BZOJ2484][SDOI2011]打地鼠(暴力) 题面 BZOJ 洛谷 题解 看到数据范围这题就应该是一个暴力题了. 先考虑假如我们知道了锤子的大小\(R*C\),那么显然只需要从左上角开始从左 ...