maven知识
mvn clean 清除项目生产的临时文件,一般在target里面
mvn package 项目打包工具,会在模块下的target目录生成对应jar或war等文件
mvn test 测试命令,或执行src/test/java/下junit的测试用例
-Dmaven.test.skip=true 跳过测试
mvn install 将打包的jar/war复制到本地仓库,配合-Dmaven.test.skip=true 这个使用
mvn deploy 将打好的包发布到远程
mvn compile
mvn package -Dmaven.test.skip=true
mvn -U 使用-U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新,而持续集成的频率应该比这高很多。
mvn -v --version 显示版本信息;
mvn -V --show-version 显示版本信息后继续执行Maven其他目标;
mvn -h --help 显示帮助信息;
mvn -e --errors 控制Maven的日志级别,产生执行错误相关消息;
mvn -X --debug 控制Maven的日志级别,产生执行调试信息;
mvn -q --quiet 控制Maven的日志级别,仅仅显示错误;
mvn -Pxxx 激活 id 为 xxx的profile (如有多个,用逗号隔开);
mvn -Dxxx=yyy 指定Java全局属性;
mvn -o --offline 运行offline模式,不联网更新依赖;
mvn -N --non-recursive 仅在当前项目模块执行命令,不构建子模块;
mvn -pl --module_name 在指定模块上执行命令;
mvn -ff --fail-fast 遇到构建失败就直接退出;
mvn -fn --fail-never 无论项目结果如何,构建从不失败;
mvn -fae --fail-at-end 仅影响构建结果,允许不受影响的构建继续;
mvn -C --strict-checksums 如果校验码不匹配的话,构建失败;
mvn -c --lax-checksums 如果校验码不匹配的话,产生告警;
mvn -U 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖);
mvn -npu --no-plugin-s 对任何相关的注册插件,不进行最新检查(使用该选项使Maven表现出稳定行为,该稳定行为基于本地仓库当前可用的所有插件版本);
mvn -cpu --check-plugin-updates 对任何相关的注册插件,强制进行最新检查(即使项目POM里明确规定了Maven插件版本,还是会强制更新);
mvn -up --update-plugins [mvn -cpu]的同义词;
mvn -B --batch-mode 在非交互(批处理)模式下运行(该模式下,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值);
mvn -f --file <file> 强制使用备用的POM文件;
mvn -s --settings <arg> 用户配置文件的备用路径;
mvn -gs --global-settings <file> 全局配置文件的备用路径;
mvn -emp --encrypt-master-password <password> 加密主安全密码,存储到Maven settings文件里;
mvn -ep --encrypt-password <password> 加密服务器密码,存储到Maven settings文件里;
mvn -npr --no-plugin-registry 对插件版本不使用~/.m2/plugin-registry.xml(插件注册表)里的配置;
#################################################################################################################################################################################
仓库类型
nexus仓库类型
proxy:代理仓库----局域网内用户首先从代理仓库下载JAR包,如果代理仓库没有就从远程仓库下载到代理仓库
hosted:宿主仓库----与代理仓库相反,他没有远程仓库,自己就是终点。主要用于多个模块开发时,将某一模块代码打成JAR包,发布到宿主仓库,其他项目成员可以从这个仓库下载你的模块JAR包,在其他模块中使用这个模块类的功能(平台的补丁包之类的,基线每次出的安装包)
group:仓库组----创建的仓库组没有Release和Snapshot之分,不同于宿主仓库和代理仓库,在配置界面,用户可以选择Nexus中的仓库,聚合成一个虚拟仓库组。配置的顺序,决定了仓库组遍历的顺序,所以,要把常用的配置在前面,保证当用户从仓库组下载构件的时候,能够尽快的访问到包含构件的仓库,提高maven构件项目的效率。
3rd party:第三方依赖的仓库----这个数据通常是由内部人员自行下载之后发布上去
#################################################################################################################################################################################
maven依赖范围(scope)
1)test:指的是测试范围有效,在编译打包、运行时都不会使用这个依赖。例如:junit jar包。
2)compile:指的是编译范围有效,在编译、测试、打包、运行时都会将依赖存储进去。如果没有指定,就会默认使用该依赖范围。例如:hibernate jar包。
3)provided:在编译和测试的过程有效,最后生成包时不会加入,运行时自然也没效果。例如:servlet-api,因为servlet-api,tomcat等web服务器已经存在该jar包了,如果再打包可能会有冲突。
4)runtime:在测试、运行的时候依赖,在编译的时候不依赖。例如:JDBC驱动,项目代码只需要jdk提供的jdbc接口,只有在执行测试和运行项目的时候才需要实现jdbc的功能。
5)system:系统依赖范围。该依赖范围与provided所表示的依赖范围一致,对于编译和测试有效,但在运行时无效。只是使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用,systemPath元素可以引用环境变量。
依赖范围(scope) 测试classpath 编译classpath 运行classpath 例子
compile Y Y Y spring-core
provided Y servlet-api
test Y junit
runtime Y Y JDBC驱动实现
system Y Y 本地的,Maven仓库之外的类库文件
传递性依赖和依赖范围
Maven的依赖是具有传递性的,比如A->B,B->C,那么A间接的依赖于C,这就是依赖的传递性,其中A对于B是第一直接依赖,B对于C是第二直接依赖,C为A的传递性依赖。
在平时的开发中,如果我们的项目依赖了spring-core,依赖范围是compile,spring-core又依赖了commons-logging,依赖范围也是compile,那么我们的项目对于commons-logging这一传递性依赖的范围也就是compile。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。我们通过下面这个表格来说明,其中最左边一栏是第一直接依赖,最上面那一栏为第二直接依赖。中间交叉的是传递性依赖范围
compile test Provided Runtime
Compile Compile Runtime
Test Test Test
Provided Provided Provided Provided
Runtime Runtime Runtime
依赖调解
A->B->C->X(1.0),A->D-X(2.0) 2条路径都依赖x
1.路径长短不一致,选择短的那个包依赖
2.路径长短一致,依赖写在前则先依赖,例如:A->B->F(1.0),A->C->F(2.0),会选F(1.0)
3.可选依赖不会被传递,如A->B,B->C,B->D,A对B直接依赖,B对C和D是可选依赖,那么在A中不会引入C和D。可选依赖通过optional元素配置,true表示可选。如果要在A项目中使用C或者D则需要显式地声 明C或者D依赖。
设置传递依赖是否下载相应的jar包,设置下面代码则不会下载依赖传递的包
pom.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>package.xml</descriptor>
</descriptors>
<finalName>default</finalName>
</configuration>
<executions>
<execution>
<id>package_war</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
package.xml
<assembly>
<id>war-fragment</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>WEB-INF/lib</outputDirectory>
<outputFileNameMapping>
${artifact.artifactId}.jar
</outputFileNameMapping>
<useTransitiveDependencies>false</useTransitiveDependencies>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<useDefaultExcludes>true</useDefaultExcludes>
<directory>src/main/pkgresources</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
</fileSets>
</assembly>
#################################################################################################################################################################################
在Nexus仓库中,一个仓库一般分为public(Release)仓库和SNAPSHOT仓。前者存放正式版本,后者存放快照版本。
在项目pom.xml中,指定版本号带-SNAPSHOT,那么打出的包就是一个快照版本。
快照版本和正式版本的区别:
本地获取这些依赖的机制不同。
如果你依赖一个库的正式版本,构建的时候,先在本地仓库中查找是否已经有了这个依赖库,如果没有的话才会去远程仓库去拉取。如果发布一个xxx-1.1.jar到远程仓库,有一个项目依赖这个库,第一次构建会把这个jar拿到本地仓库中,以后再构建就不会去访问远程仓库了。你修改了代码发布上去,也不会再拉,本地这个库不能得到更新。除非升级这个版本 xxx-1.2.jar,然后通知项目,修改依赖为这个版本。
如果构建频繁会疯掉。
那么使用-SNAPSHOT,每天构建时构建快照版本,xxx-1.1-SNAPSHOT,如果有则下载来使用。即使本地仓库已经有,也会去访问远程仓库,看是否是最新的。
在配置Maven的Repository的时候,有个配置项,可以配置对SNAPSHOT版本向远程仓库的查找频率。分别always,daily(第一次,当天的其他时候不查看),interval(设置一个以分钟为单位的间隔),never。
Maven仓库根据版本号类型发布到对应仓库,如果2.0.0.0则发布到release仓库里,如果2.0.0.0-SNAPSHOT则发布到快照版本里
##########################################################################################################################################################################
打印工程的依赖树:mvn dependency:tree -Doutput=a.txt
##################################################################################################################################################
构建Maven项目的时候,如果没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件。
src/main/java和src/test/java
这两个目录中的所有*.java文件会分别在comile和test-comiple阶段被编译,编译结果分别放到了target/classes和targe/test-classes目录中,但是这两个目录中的其他文件都会被忽略掉。
src/main/resouces和src/test/resources
这两个目录中的文件也会分别被复制到target/classes和target/test-classes目录中。
target/classes
打包插件默认会把这个目录中的所有内容打入到jar包或者war包中。
###################################################################################################################################
怎么处理从maven上取的包,比如不带版本号,Foudadation对于平台的包采用以下方式,在package.xml文件中进行名字的匹配
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>war-fragment</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>WEB-INF/lib</outputDirectory>
<outputFileNameMapping>
${artifact.artifactId}.jar
</outputFileNameMapping>
<useTransitiveDependencies>false</useTransitiveDependencies>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<useDefaultExcludes>true</useDefaultExcludes>
<directory>src/main/pkgresources</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
</fileSets>
</assembly>
########################################################################################################################################
1.Maven的配置文件(Maven的安装目录/conf/settings.xml ) 和 Maven仓库下(默认的Maven仓库的是用户家目录下的.m2文件,可以另行制定)的settings.xml文件
在Maven中提供了一个settings.xml文件来定义Maven的全局环境信息。这个文件会存在于Maven的安装目录的conf子目录下面,或者是用户家目录的.m2子目录下面。我们可以通过这个文件来定义本地仓库、远程仓库和联网使用的代理信息等。
其实相对于多用户的PC机而言,在Maven安装目录的conf子目录下面的settings.xml才是真正的全局的配置。而用户家目录的.m2子目录下面的settings.xml的配置只是针对当前用户的。
当这两个文件同时存在的时候,那么对于相同的配置信息用户家目录下面的settings.xml中定义的会覆盖Maven安装目录下面的settings.xml中的定义。
用户家目录下的settings.xml文件一般是不存在的,但是Maven允许我们在这里定义我们自己的settings.xml,如果需要在这里定义我们自己的settings.xml的时候就可以把Maven安装目录下面的settings.xml文件拷贝到用户家目录的.m2目录下,然后改成自己想要的样子。
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>4.26.1</version>
</dependency>
(一)Maven工程中引入了第三方的jar包该如何打包
- 执行发布包到本地仓库mvn install:install-file -Dfile=lib/smartv-common-0.3.9-SNAPSHOT.jar -DgroupId=local.lib -DartifactId=smartv-common -Dversion=0.3.9 -Dpackaging=jar
- 然后在根目录的pom文件下执行 mvn clean package -Dmaven.test.skip=true命令进行打包
(二)打包时候如何根据不同环境指定不同的配置文件进行打包
一、POM中profile的配置
首先是profile配置,在pom.xml中添加如下profile的配置:
<profiles>
<profile>
<!-- 本地开发环境 -->
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<profile>
<!-- 生产环境 -->
<id>pro</id>
<properties>
<profiles.active>pro</profiles.active>
</properties>
</profile>
</profiles>
这里定义了三个环境,dev(开发环境)、test(测试环境)、pro(生产环境),其中开发环境是默认激活的(activeByDefault为true),这样如果在不指定profile时默认是开发环境。
同时每个profile还定义了两个属性,其中profiles.active表示被激活的profile的配置文件的目录。
二、工程目录
针对不同的环境,我们定义不同的配置文件,而这些配置文件都做为资源文件放到maven工程的resources目录下,即src/main/resources目录下,且各个环境的配置分别放到相应的目录下,而所有环境都公用的配置,直接放到src/main/resources目录下即可。如下图所示:
如图所示,开发环境、测试环境、生产环境的配置文件分别放到src/main/resources目录下的dev、test、pro三个子目录中,剩余公共的配置文件放于resources目录下。
三、POM文件中build配置
在pom中的build节点下,配置资源文件的位置,如下所示:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 资源根目录排除各环境的配置,防止在生成目录中多余其它目录 -->
<excludes>
<exclude>test/*</exclude>
<exclude>pro/*</exclude>
<exclude>dev/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
</resource>
</resources>
</build>
首先第一个资源文件位置src/main/resources需要排队提各个环境的配置文件,各个环境的配置我们在第二个节点中通过前面在profile中配置的profiles.active属性来指定。即src/main/resources/${profiles.active}。这样在激活指定的profile时,会加载指定目录下的配置文件,如当前激活的是pro profile,那么这个资源目录就是src/main/resources/pro。这样就达到了不同环境加载不同配置的目的。
四、项目编译生成
所有需要的配置就完成了,通过在运行maven命令时指定不同的profile即可构建不同环境需要的war包或发布到不同的环境了 。如:
mvn clean package -Ppro 即构建出生产环境需要的war包
由于默认的profile是dev,所以如果我们不指定profile,那么加载就是开发环境dev下的配置文件了。即我们在本地开发测试时,不用关心profile的问题。