Maven 拾遗
01. maven 概要
首先我把 maven 的概念快速的梳理一下,让我们快速地建立起一个比较精确的 maven 应用场景。
maven 不是 ant,也不是 make,以前接触的构建工具,需要写一些详细的步骤,如: compile project1/src/*.java 等类似的语句。
maven 采用了"约定优于配置"的方法,一些开发常用的操作和步骤已经固化在 maven中,所以使用者不再需要编写那些语句。
maven 内置了开发流程的支持,它不仅能够编译,同样能够打包、发布,也能够一气呵成做完这些所有的步骤。
maven 不是 ivy,依赖管理是 maven 的功能之一,maven 在依赖关系中加入了scope 的概念,进一步细化了依赖关系的划分。
maven 将自己定位为一个项目管理工具。它负责管理项目开发过程中的如下几乎所有的东西。
a.版本:maven有自己的版本定义和规则;
b.构建:maven支持许多种的应用程序类型,对于每一种支持的应用程序类型都定义好了一组构建规则和工具集;
c.输出物管理:maven可以管理项目构建的产物,并将其加入到用户库中。这个功能可以用于项目组和其他部门之间的交付行为;
d.依赖关系 : maven对依赖关系的特性进行细致的分析和划分,避免开发过程中的依赖混乱和相互污染行为;
e.文档和构建结果:maven的site命令支持各种文档信息的发布,包括构建过程的各种输出,javadoc,产品文档等;
f.项目关系:一个大型的项目通常有几个小项目或者模块组成,用maven可以很方便地管理;
h.移植性管理 : maven可以针对不同的开发场景,输出不同种类的输出结果;
02. maven 生命周期
maven把项目的构建划分为不同的生命周期(lifecycle),包括:验证、编译、测试、打包、部署。
maven中所有的执行动作(goal)都需要指明自己在这个过程中的执行位置,然后maven执行的时候,就依照过程的发展依次调用这些goal进行各种处理。
这个也是maven的一个基本调度机制。一般来说,位置稍后的过程都会依赖于之前的过程。
当然,maven同样提供配置文件,可以依照用户要求,跳过某些阶段。
03. maven "约定优于配置"
maven 中 "约定优于配置" 并不是完全不可以修改的,他们只是一些配置的默认值而已。
但是使用者除非必要,并不需要去修改那些约定内容。
maven默认的文件存放结构如下:
/项目目录 pom.xml 用于maven的配置文件
/src 源代码目录
/src/main 工程源代码目录
/src/main/java 工程java源代码目录
/src/main/resource 工程的资源目录
/src/test 单元测试目录
/src/test/java
/target 输出目录,所有的输出物都存放在这个目录下
/target/classes 编译之后的class文件
每一个阶段的任务都知道怎么正确完成自己的工作。
如 compile 任务就知道从 src/main/java 下编译所有的 java 文件,并把它的输出class文件存放到 target/classes 中。
采用"约定优于配置"的策略可以减少修改配置的工作量,也可以降低学习成本,更重要的是,给项目引入了统一的规范。
04. maven 版本规范
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
maven 使用4个要素来唯一定位某一个输出物: groupId:artifactId:packaging:version 。如 org.springframework:spring:2.5 。
groupId 团体,公司,小组,组织,项目,或者其它团体。团体标识的约定是,它以创建这个项目的组织名称的逆向域名开头。
artifactId 在groupId下的表示一个单独项目的唯一标识符。比如我们的 tomcat, commons 等。不要在 artifactId 中包含点号(.)。
version 一个项目的特定版本。发布项目有一个固定的版本标识来指向该项目的某一个特定的版本。
虽然项目的打包格式也是 Maven 坐标的重要组成部分,但是它不是项目唯一标识符的一个部分。
一个项目的 groupId:artifactId:version 使之成为一个独一无二的项目;你不能同时有一个拥有同样的 groupId, artifactId,version 标识的项目。
packaging 项目的类型,默认是 jar,描述了项目打包后的输出。
maven 在版本管理时候可以使用几个特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。
比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:
SNAPSHOT:用于开发过程,Maven 就会在安装或发布这个组件的时候将该符号展开为一个日期和时间值,转换为UTC时间。
例如,"1.0-SNAPSHOT"会在2010年5月5日下午2点10分发布时候变成 1.0-20100505-141000-1。
LATEST:指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个 snapsho t版,具体看哪个时间最后。
RELEASE:指最后一个发布版。
05. maven 依赖管理
个人认为依赖管理是 maven 中最吸引人的功能特性,这个特性让开发者只需要关注代码的直接依赖。
比如我们用了spring,就加入spring 依赖说明就可以了,至于 spring 自己还依赖哪些外部的东西,maven 帮我们搞定。
任意一个外部依赖说明包含如下几个要素:groupId, artifactId, version, scope, type, optional。其中前3个是必须的,各自含义如下:
这里的 version 可以用区间表达式来表示,比如 (2.0,) 表示>2.0,[2.0,3.0) 表示 2.0<=ver<3.0;多个条件之间用逗号分隔,比如[1,3),[5,7]。
maven 认为程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以 maven 中的依赖关系有作用域(scope)的限制。
scope 包含如下的取值:
compile(编译范围)---> compile 是默认的范围,编译范围依赖在所有的classpath中可用,同时它们也会被打包。
provided(已提供范围) ---> provided 依赖只有在当 JDK 或者一个容器已提供该依赖之后才使用。
比如你开发了一个web应用,在编译 classpath 中需要可用的 Servlet API 来编译 servlet,又不想在打包好的 WAR 中包含这个 Servlet API。
runtime(运行时范围 --> runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。
比如你可能在编译的时候只需要 JDBC API JAR,而只有在运行的时候才需要 JDBC 驱动实现。
test(测试范围)--> test 范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
system(系统范围) --> system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中 JAR 文件的路径。
<dependency>
<groupId>org.wltea</groupId>
<artifactId>analyzer</artifactId>
<version>2012_u6</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/analyzer-2012_u6.jar</systemPath>
</dependency>
注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)。
type 一般在pom引用依赖时候出现,其他时候不用, optional 是否可选依赖。
依赖也可以是可选的,比如我们代码中没有任何cache依赖,但是hibernate可能要配置cache,所以该cache的依赖就是可选的。
06. maven 多项目管理
maven的多项目管理也是非常强大的。一般来说,maven要求同一个工程的所有子项目都放置到同一个目录下,每一个子目录代表一个项目,比如
总项目/ pom.xml 总项目的 pom 配置文件
子项目1/pom.xml 子项目1的 pom 文件
子项目2/ pom.xml 子项目2的 pom 文件
按照这种格式存放,就是继承方式,所有具体子项目的pom.xml都会继承总项目pom的内容,取值为子项目pom内容优先。
要设置继承方式,首先要在总项目的pom中加入如下配置
<modules>
<module>simple-weather</module>
<module>simple-webapp</module>
</modules>
其次在每个子项目中加入
<parent>
<groupId>org.sonatype.mavenbook.ch06</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
当然,继承不是唯一的配置文件共用方式,maven还支持引用方式。引用pom的方式更简单,在依赖中加入一个type为pom的依赖即可。
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
07. maven 内置属性
用户可以在maven中定义一些属性,然后在其他地方用${xxx}进行引用。比如:
<properties>
<var1>value1</var1>
</properties>
maven 提供了三个隐式的变量,用来访问系统环境变量、POM信息和 maven 的 settings:
env 暴露操作系统的环境变量,比如 env.PATH
project 暴露 POM 中的内容,用点号(.)的路径来引用POM元素的值,比如 ${project.artifactId}。另外,java的系统属性比如user.dir等,也暴露在这里。
settings 暴露 maven 的 settings 的信息,也可以用点号(.)来引用。
08. maven profile
profile 是 maven 的一个重要特性,它可以让 maven 能够自动适应外部的环境变化。
比如同一个项目,在linux下编译linux的版本,在win下编译win的版本等。
一个项目可以设置多个 profile,也可以在同一时间设置多个 profile 被激活(active)的。
自动激活的 profile 的条件可以是各种各样的设定条件,组合放置在 activation 节点中,也可以通过命令行直接指定。
profile 包含的其他配置内容可以覆盖掉 pom 定义的相应值。
如果认为 profile 设置比较复杂,可以将所有的 profiles 内容移动到专门的 profiles.xml 文件中,不过记得和 pom.xml 放在一起。
09. maven 配置文件
maven的主执行程序为 mvn.bat,linux下为mvn.sh,这两个程序都很简单,它们的共同用途就是收集一些参数,然后用 java.exe来运行maven的Main函数。
maven 同样需要有配置文件,名字叫做 settings.xml,它放在两个地方,一个是 maven 安装目录的conf目录下,对所有使用该 maven 的用户都起作用。
我们称为主配置文件,另外一个放在 %USERPROFILE%/.m2/settings.xml 下,我们成为用户配置文件,只对当前用户有效,且可以覆盖主配置文件的参数内容。
还有就是项目级别的配置信息了,它存放在每一个 maven 管理的项目目录下,叫 pom.xml,主要用于配置项目相关的一些内容。
当然,如果有必要用户也可以在 pom 中写一些配置,覆盖住配置文件和用户配置文件的设置参数内容。
一般来说,settings文件配置的是比如repository库路径之类的全局信息,具体可以参考官方网站的文章。
10. maven 本地安装和中央库发布
在maven中一般都会用到安装库文件的功能,一则是我们常用的hibernate要使用jmx库,但是因为sun的license限制,所以无法将其直接包含在repository中。
所以我们使用mvn命令把jar安装到我们本地的repository中
mvn install:install-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=/path/to/file
如果我们想把它安装到公司的repository中,需要使用命令
mvn deploy:deploy-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=公司私服地址
对于我们的工程输出,如果需要放置到公司的repository中的话,可以通过配置 pom 来实现
<distributionManagement>
<repository>
<id>mycompany-repository</id>
<name>MyCompany Repository</name>
<url>公司私服地址</url>
</repository>
</distributionManagement>
11. maven 常用命令
1. 创建Maven的普通java项目:
mvn archetype:create -DgroupId=packageName -DartifactId=projectName
2. 创建Maven的Web项目:
mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp
3. 编译源代码: mvn compile
4. 编译测试代码:mvn test-compile
5. 运行测试:mvn test
6. 产生site:mvn site
7. 打包:mvn package
8. 在本地Repository中安装jar:mvn install
9. 清除产生的项目:mvn clean
10. 生成eclipse项目:mvn eclipse:eclipse
11. 生成idea项目:mvn idea:idea
12. 组合使用goal命令,如只打包不测试:mvn -Dtest package
13. 编译测试的内容:mvn test-compile
14. 只打jar包: mvn jar:jar
15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
16. 清除eclipse的一些系统设置:mvn eclipse:clean
17. 修改项目版本 mvn versions:set -DnewVersion=1.2 然后 mvn versions:commit
Maven 拾遗的更多相关文章
- Maven (一)--- 入门和依赖
部分图片来自参考资料 问题 : - maven 生命周期是怎么样的 - mvn clean install 与 mvn clean deploy 的区别是什么 概述 Maven 是一种构建项目的工具, ...
- 【分享】标准springMVC+mybatis项目maven搭建最精简教程
文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...
- 理解Maven中的SNAPSHOT版本和正式版本
Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...
- 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo
Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...
- 安装eclipse的maven插件
我们团队用maven来管理项目需要的库文件,其实以前都没听过maven,第一次接触这个,师兄要我直接去装下这个,开始以为还挺简单的,没想到中间遇到了一些小麻烦,现在把我成功安装maven的过程分享下, ...
- MAVEN学习-第一个Maven项目的构建
MAVEN安装成功之后就可以进行项目的构建和管理了: 为什么要用maven进行项目的构建和管理? 对于初学者来说一个最直接的也是最容易里的优点在于JAR包的管理,相对于以前开发一个项目的时候我们需要用 ...
- Maven 代理设置
在maven的安装目录下 %MAVEN_HOME%/conf/setting.xml 中进行设置 <proxies> <!-- proxy | Specificatio ...
- spring maven pom.xml设置
spring pom.xml设置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...
- maven依赖查询地址
http://search.maven.org/#search%7Cga%7C1%7C
随机推荐
- java把指定文字输出为图片流,支持文字换行
public class IamgeUtils { private static final int WIDTH = 350; private static final int HEIGHT = 10 ...
- 制作高仿QQ的聊天系统(上)—— 布局文件 & 减少过度绘制
由于没有自己的服务器,我就找了个能实现双方通信的SDK,这个SDK是友盟的用户反馈SDK.本系列的博文关注的不是网络通信,而是如何在网络通信机制已经做好的情况下,做出一个可用的聊天系统.其实,刚开始做 ...
- org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.xugao.bean.MemberLevel.memberpointrate
由于数据不合法的原因,好几次遇到: org.hibernate.PropertyAccessException: Null value was assigned to a property of pr ...
- Hash dump神器 (转)
在Win7 x64位下无压力测试通过. 0 / INTRO========= Quarks PwDump 是一个Win32环境下的系统授权信息导出工具,目前除此之外没有任何一款工具可以导出如此全面的信 ...
- MFC中如何给静态文本框添加消息响应
需要两个步骤: 第一个: 是改变它的ID(默认情况下所有的静态文本框的ID都为IDC_STATIC,你需要改变他的ID为其他的值). 第二个: 是在它的属性对话框中选中Notify选项,VS是将该属性 ...
- 【Eclipse】Eclipse性能调优
Eclipse性能调优 eclipse 吃内存_百度搜索 eclipse 性能调优之内存分配 - Defonds 的专栏 - CSDN博客 优化JVM参数提高eclipse运行速度 - Java综合 ...
- XGBoost浅入浅出
http://wepon.me/ XGBoost风靡Kaggle.天池.DataCastle.Kesci等国内外数据竞赛平台,是比赛夺冠的必备大杀器.我在之前参加过的一些比赛中,着实领略了其威力,也取 ...
- ASP.NET MVC 重命名[命名空间]而导致的错误及发现的ASP.NET MVC Bug一枚
使用VS2012新建了一个Asp.net mvc5的项目,并把项目的命名空间名称更改了(Src更改为UXXXXX),然后就导致了以下错误 刚开始以后是项目的属性中的命名空间没有更改过来的问题,但我在重 ...
- python 读取单所有json数据写入mongodb(单个)
<--------------主函数-------------------> from pymongo import MongoClientfrom bson.objectid impor ...
- Unity3D for Mac 破解
每次版本更新又忘记怎么搞了.干脆记下来! 1安装Unity 2安装成功后打开Applecation>Unity>Unity(右击显示包内容)>contents>MacOS 3用 ...