maven生命周期
在Maven中有三套独立的生命周期:
1. Clean Lifecycle:在进行真正的构建之前进行一些清理工作
2. Default Lifecycle:构建的核心部分,编译、测试、打包、部署
3. Site Lifecycle:生成项目报告、生成站点、发布站点
Maven最重要的就是默认的构建生命周期,在这个生命周期中有23个阶段,不过最重要的是以下几个阶段:编译、测试、打包、安装、部署
要注意非常重要的一点是任何一个阶段运行的时候,他前面所有的阶段都会被运行。
Maven生命周期中常用的指令:
mvn compile //让当前项目经历生命周期中的1–>7 阶段 :完成编译主源代码编译
mvn package //让当前项目经历生命周期中的1–>17阶段 :完成打包
mvn install //让当前项目经历生命周期中的1–>22阶段 :完成包安装到本地仓库
mvn deploy //让当前生命经历生命周期中的1–>23阶段 :完成包部署到中心库中
Maven中scope标签详解
Maven一个哲学是约定大于配置(Convention Over Configuration)。所以maven中很多地方都有默认值,scope的默认值是compile。
Scope的分类:
1.compile:默认值,他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去,会随着项目一起发布。
2.test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,也不会随着项目发布。例如:junit
3.runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。在运行时使用,例如JDBC驱动,适用运行和测试阶段
4.provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作
5.system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径
scope的依赖传递
A依赖B,B依赖C。当前项目为A,只当B在A项目中的scope,那么c在A中的scope是如何得知呢?
当C是test或者provided时,C直接被丢弃,A不依赖C;(排除传递依赖)
否则A依赖C,C的scope继承与B的scope
scope使用策略
在Maven1中,需要把依赖所需要的包每个列出。这对于使用类似如hibernate的用户来说所操的心太多了,而且也不方便。在Maven2中实现了传递依赖,如此对于Hibernate所依赖的包,Maven2会自动下载,开发人员只需关心Hibernate即可。所以可以看出列出所需要的每个jar是在maven1中的功能,Maven2认为自动下载是一种改进。
这样就产生了一个问题:Maven2虽然把编译时需要的jar都下载了,但并不是所有编译需要的jar在打成war包后运行时也需要。所以也就发现有许多的jar是不需要的,以至war包比较大。
策略1:
对于容器提供的或者测试需要的,可以直接在pom.xml中去掉,如以下依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
策略2:
对于第三方jar包,传递依赖到war包的,但发布时并不需要的。
如:我们项目中使用了webwork-2.2.3.jar。可以我们在打包后发现在war下的lib中多了spring-web-1.2.jar,可是我们项目并不需要这个jar。
第一种办法:借用provided
虽然provided的本意是指jdk或者容器提供的,只是编译中使用,但不会打到war中,但我们也可借用。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
第二种办法: 使用exclusions; (效果与第一种相同)
<dependency>
<groupId>opensymphony</groupId>
<artifactId>webwork</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
策略三:
对于我们公司内部开发的jar包,我们都加上true,这样可以使引用这些jar的项目不会产生传递依赖。
如:项目mycom-csa中使用了mycom-cas-client-1.0.3.jar, mycom-cas-client-1.0.3.jar又使用了mycom-common-security-1.0.3.jar。所以我们在对mycom-csa打包时会把mycom-common-security-1.0.3.jar打进package中。我们当然可以参考“策略二”,但最好的方法是:可以通知开发mycom-cas-client-1.0.3.jar的同时在mycom-cas-client-1.0.3.jar的pom.xml中对dependency修改为:
<dependency>
<groupId>com.mycom</groupId>
<artifactId>mycom-common-security</artifactId>
<version>1.0.3-SNAPSHOT</version>
<optional>true</optional>
</dependency>
添加true ,这样我们再打包时mycom-csa中就不会出现mycom-common-security-1.0.3.jar了。
maven编译常用命令
1.1、mvn clean install -DskipTests
1.2、mvn clean install -Dmaven.test.skip=true
1.3、mvn clean install -D maven.javadoc.skip=true
注意事项:
Intellij IDEA 中maven编译中文出现乱码
需要在Settings–maven–runner–VM Options添加 -Dfile.encoding=GB2312
参考文章
Maven探析与应用
http://blog.csdn.net/column/details/clfmaven.html
《Maven进阶》1.maven 项目生命周期与构建原理
http://blog.csdn.net/luanlouis/article/details/50492163
Maven实战:Maven生命周期
https://www.cnblogs.com/xrq730/p/5527254.html
maven中scope标签详解
http://blog.csdn.net/cd18333612683/article/details/66478332
Maven中的dependency的scope作用域详解
http://makaidong.com/a564663276/1/53219_12316918.html