扯扯maven的蛋
同样是放在有道云笔记里,各种散乱加发霉,抽空来整理整理,分几个部分来扯扯maven。
一、Maven是啥求。
Maven 为Apache 组织中的开源项目,主要服务于基于Java 平台的项目构建、依赖管理和项目信息管理。这样说大家又要问了,啥时构建,啥是依赖管理啊。构建说起来可简单,每个码农都在项目中接触过。何为构建呢?编译、运行单元测试、生成文档、打包和部署等烦琐且不起眼的工作上,这就是构建。在软件项目过程中,手动的构建会占用大量的时间以及精力,于是有人用软件的方法让这一系列工作完全自动化,使得软件的构建可以像全自动流水线一样。
除此之外,Maven还是一个依赖管理工具以及项目信息管理工具。它提供了中央仓库,能帮我们自动下载构件。在这个开源的年代里,几乎任何Java应用都会借用一些第三方的开源类库,传统的方式当然就是手动下载开源的jar包,手动导入到项目中。随着依赖的增多,版本不一致、版本冲突、依赖臃肿等问题都会接踵而来。手工解决这些问题是十分枯燥的,这时候就需要maven大展宏图了。Maven通过一个坐标系统可以准确的定位到每一个构建(artifact),也就是通过一组坐标Maven能够找到任何一个Java 类库(如jar文件)。
Maven的坐标系统
如上文所述,maven通过一个坐标系统可以准确的定位到每一个构建。maven定义了这样一组规则:groupId、artifactId、version、packaging、classifier五元组来表示一个唯一的构建。
- groupId:定义当前maven项目隶属的实际项目。
- artifactId:定义实际项目中的一个maven项目(模块),推荐的做法是使用实际的项目名称作为artifactId的前缀。
- version:定义maven当前所处的版本。
- packaging:定义maven项目的打包方式,可选的(默认为jar)
- classifier:该元素用来帮助定义构建输出的一些附属构件,该属性不能直接定义。
Maven的安装:
Maven 是一个基于 Java 的工具,所以要做的第一件事情就是安装 JDK。Maven不同版本对jdk的版本有不同的要求,Maven 3.3 要求 JDK 1.7 或以上。
从以下网址下载 Maven 3.3.9:http://maven.apache.org/download.html,解压文件到你想要的位置来安装 Maven 3.3.9。
解压完成之后配置对应机器的环境变量,M2_HOME、PATH。
环境变量配置完成之后,打开控制台,输入mvn --version来验证maven是否安装成功。
二、Maven仓库
在 Maven 的术语中,仓库是一个位置(place),例如目录,可以存储所有的工程 jar 文件、library jar 文件、插件或任何其他的工程指定的文件。
Maven 仓库有三种类型:
- 本地:Maven 本地仓库是机器上的一个文件夹,它在你第一次运行任何 maven 命令的时候创建,Maven 本地仓库默认被创建在 %USER_HOME% 目录下。
- 中央:Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。
- 远程:如果 Maven 在中央仓库中也找不到依赖的库文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。
三、Maven配置
settings.xml
maven的配置文件为settings.xml,在下面路径中可以找到这个文件,分别为:
- $M2_HOME/conf/settings.xml:全局设置,在maven的安装目录下;
- ${user.home}/.m2/settings.xml:用户设置,需要用户手动添加,可以将安装目录下的settings.xml文件拷贝过来修改。
一般而言,该文件不需要修改,但是在国内访问maven的中央仓库太慢了,所以最好配置mirror用于拦截maven对remote repository的相关请求,把请求里的remote repository地址,重定向到mirror里配置的地址。
修改maven根目录下的conf文件夹中的settings.xml文件,内容如下:
- <mirrors>
- <mirror>
- <id>alimaven</id>
- <name>aliyun maven</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
- <mirrorOf>central</mirrorOf>
- </mirror>
- </mirrors>
pom.xml
POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程。POM 也包含了目标和插件。当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标。
POM举例:
- <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><!--maven2.0必须是这样写,现在是maven2唯一支持的版本-->
- <!-- The Basics -->
- <groupId>...</groupId> <!--创建项目的组织或团体的唯一 Id,例如:org.apache.maven-->
- <artifactId>...</artifactId> <!--指定工程名例如:appfuse-->
- <version>...</version> <!--指定版本号-->
- <packaging>...</packaging> <!--打包物的扩展名,一般有 JAR,WAR,EAR 等-->
- <classifier>...</classifier> <!--projects are displayed as groupId:artifactId:packaging:classifier:version-->
- <name>...</name> <!--一项目的显示名,常用于 Maven 生成的文档-->
- <url>...</url> <!--组织的站点,常用于 Maven 生成的文档-->
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.0</version>
- <type>jar</type> <!--相应的依赖产品包形式,如jar,war-->
- <scope>test</scope>
- <!--用于限制相应的依赖范围,包括以下的几种变量
- compile :默认范围,使用该依赖范围,对于编译,测试,运行三种classpath都有效。
- provided:对于编译和测试classpath有效,但运行时无效。
- test:测试依赖范围。
- system:需要外在提供相应得元素。通过systemPath来取得.
- runtime:运行时依赖范围。使用该依赖范围,对于测试和运行classpath有效,但是编译时无效。
- -->
- <optional>true</optional>
- <!--dependency里面的exclusions:如果X需要A,A包含B依赖,那么X可以声明不要B依赖,只要在exclusions中声明exclusion。optional是不会install或者使用B,而exclusion是将B从依赖树中是删除。例如appfuse不想使用hibernate,但是appfuse是集成hibernate的,所以就排除掉:-->
- <exclusions>
- <exclusion>
- <groupId>org.appfuse</groupId>
- <artifactId>appfuse-hibernate</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- <build>
- <resource>
- <directory>src/main/plexus</directory>
- <includes>
- <include>configuration.xml</include>
- </includes>
- <excludes>
- <exclude>**/*.java</exclude>
- <exclude>**/.svn/*</exclude>
- </excludes>
- </resource>
- <!--
- includes:指定包含文件的patterns,符合样式并且在directory目录下的文件将会是包含进project的资源文件
- excludes:指定不包含在内的patterns,如果includes与excludes有冲突,那么excludes胜利,那些符合冲突样式的文件还是不会包含进来的
- -->
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.0</version>
- <extensions>false</extensions>
- <inherited>true</inherited>
- <configuration>
- <classifier>test</classifier>
- </configuration>
- <dependencies>...</dependencies>
- <executions>...</executions>
- </plugin>
- </plugins>
- </build>
- </project>
三、Maven生命周期
Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),这个生命周期可以从两方面来理解,第一,顾名思义,运行Maven的每个步骤都由它来定义的,这种预定义的默认行为使得我们使用Maven变得简单,相比而言,Ant的每个步骤都要你手工去定义。第二,这个模型是一种标准,在不同的项目中,使用Maven的接口是一样的,这样就不用去仔细理解每个项目的构建了,一般情况下,mvn clean install 这样的命令是通用的。我想,一定是吸收了许多项目的经验,Maven才能定义出如此完善的模型。
Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,初学者容易将Maven的生命周期看成一个整体,其实不然。这三套生命周期分别是:
- Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
- Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
- Site Lifecycle 生成项目报告,站点,发布站点。
我再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site运行所有这三套生命周期。
知道了每套生命周期的大概用途和相互关系以后,来逐个详细看一下每套生命周期,Clean和Site相对比较简单,先解释一下。
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean,这个的clean是Clean生命周期的一个阶段。有点绕?要知道有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:
- pre-clean 执行一些需要在clean之前完成的工作
- clean 移除所有上一次构建生成的文件
- post-clean 执行一些需要在clean之后立刻完成的工作
mvn clean中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean,如果我们运行 mvn post-clean,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。
下面看一下Site生命周期的各个阶段:
- pre-site 执行一些需要在生成站点文档之前完成的工作
- site 生成项目的站点文档
- post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
- site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。
最后,来看一下Maven的最重要的Default生命周期,绝大部分工作都发生在这个生命周期中,这里,我只解释一些比较重要和常用的阶段:
- validate
- generate-sources
- process-sources
- generate-resources
- process-resources 复制并处理资源文件,至目标目录,准备打包。
- compile 编译项目的源代码。
- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources 复制并处理资源文件,至目标测试目录。
- test-compile 编译测试源代码。
- process-test-classes
- test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
- prepare-package
- package 接受编译好的代码,打包成可发布的格式,如 JAR 。
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install 将包安装至本地仓库,以让其它项目依赖。
- deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
基本上,根据名称我们就能猜出每个阶段的用途,关于其它阶段的解释,请参考 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
记住,运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install的时候,代码会被编译,测试,打包。
此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。
四、Maven常见命令
maven常见命令如下:
五、Maven && Eclipse
六、Maven之乱七八糟
实验室有时候需要把某一个包安装到artifactory的内部仓库里,便于开发与部署。
当用“mvn install”命令的时候,Maven仅仅打包和安装构件到本地仓库,要把它安装到Artifactory内部仓库中,我们需要使用deploy命令。如果直接使用deploy,可能会遇到 Error code 401, User anonymous is not permitted to deploy 的问题,原因是你没有权限访问本地的maven库。
这时候就需要在settings.xml中添加一条额外的配置
- <servers>
- <server>
- <id>free4lab</id>
- <username>admin</username>
- <password>password</password>
- </server>
- </servers>
配置完settings.xml之后,如果直接执行deploy命令可能还会报错:Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter -> [Help 1]
这时候还需要配置对应maven工程的pom.xml文件,增加如下配置:
- <!--用于配置分发管理,配置相应的产品发布信息,主要用于发布,在执行mvn deploy后表示要发布的位置 -->
<distributionManagement>- <repository>
- <id>free4lab</id>
- <name>Free4lab Repository</name>
- <url>http://maven.free4lab.com/artifactory/libs-snapshot-local</url>
- </repository>
- </distributionManagement>
Maven项目获取classpath和资源文件路径:
在maven项目中,配置文件放在maven工程的src/main/resources资源文件夹下,java文件在src/main/java下,如何在java文件中加载配置文件。使用如下代码:
- MyClass.class.getClassLoder().getResource(FILE_NAME).getPath();
扯扯maven的蛋的更多相关文章
- 【面向对象】用大白话扯扯那"神奇"的面向对象编程思维(二)
前言: 上一章我们用大白话讲解了一下面向对象的编程思维,那么这一张我们来讲讲如何用面向对象来书写代码.终于到了激动人心的时刻了..... 传送门:https://www.cnblogs.com/sy1 ...
- Cocostudio学习笔记(1) 扯扯蛋 + 环境搭建
转眼七月份就到了,2014已经过了一半,而我也最终算是有"一年工作经验"了,开心ing. 回想这一年Cocos2dx的游戏开发经历,去年下半年重心主要在游戏的逻辑上,而今年上半年重 ...
- 扯扯淡,写个更快的memcpy
写代码有时候和笃信宗教一样,一旦信仰崩溃,是最难受的事情.早年我读过云风的一篇<VC 对 memcpy 的优化>,以及<Efficiency geek 2: copying data ...
- 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition
我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...
- 扯扯Java中Finalization的意义
这是Stack Overflow上关于Finalizetion意义的两段讨论,这两个观点是互为补充的. 观点1: 垃圾回收器(The garbage collector)自动在后台运行(虽然它也可以被 ...
- 用大白话扯扯那"神奇"的面向对象编程思维(一)
前言: 每当提到面向对象的时候,初学者肯定都是一脸懵逼的状态,到底什么是面向对象?会用面向对象后有什么牛逼之处吗?不会用是不是就会死掉?答案肯定不会死掉,我们可以来简单的举一 个栗子 1.当你想到熊猫 ...
- 搬个小板凳,我们扯扯Docker的前生
一.新瓶装旧酒 首先我们需要知道,Docker是一个"箩筐": 1.存储:Device Mapper.BtrFS.AUFS 2.名字空间:UTS.IPC.Mount.PID.Net ...
- 以选项卡的故事扯扯js面向对象
在现在的网页中,选项卡(我自己这样子叫)是非常普遍的,也是比较基础,学了原型实现选项卡也挺久了,最近在学ES6,学了用类实现选项卡,今天就在此做个总结,别的废话也不多说. 以"貌" ...
- 随便扯扯React生命周期 --《爱看不看系列》
生命周期嘛,顾名思义,就是说组件这辈子从生下来到死掉经历的事情.先来看看一张图片,温故温故,如图: 你会发现有些周期的名字都能找出点规律,我找到的规律是凡是 Will 字母的,表示该钩子函数会在该生命 ...
随机推荐
- 解决eclipse项目下出现deployment descriptor和jax-ws web services
当你的web项目下出现这个这些鬼东西的时候,是视图的原因 1.右上角切换视图到java,看看问题解决了没,如果没有,第二步 2.window->perspective->reset per ...
- oc之封装与类之间的关系
1. 面向对象的特征-封装? 封装: 现实生活中的封装: 将很多的小东西 塞在1个大口袋里面. 好处: a. 对外部屏蔽. b. 方便管理. 代码的封装: 函数/方法 就是1种封装的体现: 将一段代码 ...
- 项目在JDK1.8环境下的一个Bug
今天发现一个已有的项目在JDK1.8环境下运行时,会报错: The type java.util.Map$Entry cannot be resolved. It is indirectly refr ...
- [ios] Xcode使用设置相关-快捷键【转】
快照: command+control+s 编辑完了可以和之前的某个版本对比,通过File->Snapshots 调试时的快捷键也像大多数 IDE 靠拢了,采用了 F5.F6.F7 简单 ...
- Python高手之路【十二】面向对象设计模式
单例模式 单例,顾名思义单个实例. class Person: __instance = None def __init__(self): pass @staticmethod def getInst ...
- 以域管理账户连接到TFS或git时,设置IE允许Cookies
在 Windows 域环境中,每个项目组会创建一个项目管理账户,在和其他项目组进行数据交互时,只需要授予该项目管理账户相应的权限,方便了权限的管理.对于项目组管理账户:domain\admin,该域账 ...
- mysql java写入时间少14小时
查看时区: mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | V ...
- android两种方式获取AsyncTask返回值
获取AsyncTask返回值,在Activity中使用. 引用链接:https://www.oschina.net/code/snippet_725438_49858#72630 [1].[代码] [ ...
- String.split()分割字符串
string.split(s[, sep[, maxsplit]]) Return a list of the words of the string s. If the optional secon ...
- NTSC色域(CIE1931)计算公式
色域(CIE1931)=ABS(RC[-6]*RC[-3]+RC[-4]*RC[-1]+RC[-2]*RC[-5]-RC[-6]*RC[-1]-RC[-4]*RC[-5]-RC[-2]*RC[-3]) ...