maven是一个项目管理工具。
依赖管理:maven对项目中jar包的管理过程。传统工具我们直接把jar包防止在项目中。maven工程真正的jar包放置在仓库中,项目中只用jar包的坐标。
仓库的种类:本地仓库、远程仓库【私服】、中央仓库
仓库之间的关系:当我们启动一个maven工程的时候,maven工程会通过pom文件中jar包的坐标去本地仓库找对应的jar包
默认情况下,如果本地仓库没有对应jar包,maven工程会自动去中央仓库下载jar包到本地仓库
在公司中,如果本地没有对应jar包,会先从私服下载jar包。如果私服没有jar包,可以从中央仓库下载 上传,也可以从本地上传
jarBa一键构建:maven自身集成了tomact插件,可以对象爱那个木进行编译,测试,打包,安装,发布等操作。
maven常用命令:clean,compile,test,package,install,deploy
maven三套声明周期:清理生命周期、默认生命周期、站点生命周期
一、Maven的安装
1、首先在官网下载安装软件
然后将下载的文件解压缩到没有中文和没有空格的路径下面
2、maven目录解释
3、环境变量配置 ,配置MAVEN_HOME ,变量值就是mavend的安装路径,如下图,然后配置path.
通过mvn -v 命令可以检测maven是否安装成功,如图
二、maven常用命令
mvn clean 清除项目编译信息 清除生命周期
mvn compile 将项目编译会生成一个target目录。里面保存了编译结果
mvn test 进行测试
mvn package 打包 默认生命周期
mvn install 将这个项目安装到仓库中
mvn deploy 发布
三、maven概念模型图
四、idea的maven配置
1、点击configure目录下的settings配置maven
或者打开→File→Settings配置maven,如下图
配置这个参数是在不联网的情况下,可以从本地找已经下载好的框架,不需要联网下载
五、创建maven的java工程项目
1、使用idea提供好的骨架创建项目
填好信息,在点击下一步
创建好的maven项目如图
把项目目录结构补全,添加资源目录,在main文件下创建一个目录resources
此时的资源目录不能作为根目录
在resouces文件夹右击
变成这样才能是资源根目录
2、不适用骨架直接创建maven的java工程,直接next
(推荐使用,因为它会自动创建资源根目录)
六、创建maven的web工程
1、使用骨架创建maven的web工程
创建效果如下:
添加依赖的作用域
maven的依赖冲突
spring-webmvc(版本为5.2.0)依赖了spring-beans,spring-aop(版本为5.2.9)也依赖了spring-beans,由于在pom文件中,将spring-webmvc写在了前面,所以在项目中spring-beans的版本为(5.2.0),但是如果希望在工程中引入spring-aop(版本为5.2.9)这就造成了依赖冲突。
如何解决依赖冲突
1 使用maven提供的依赖调节原则
第一声明者优先原则
路径者优先原则
在pom文件中定义依赖,用先声明的依赖为准。也就是根据坐标的导入顺序来确定最终使用哪个传递过来的依赖。就如同上图中的将Spring-webmvc写在了spring-aop 的上面。所以spring-beans在项目中使用的是和spring-webmvc相同的版本。
2 排除依赖
使用exclusions标签将传递过来的依赖排除出去。如果将spring-webmvc依赖的spring-beans排除出去,项目中使用的将是spring-aop传递过来的spring-beans。
3 版本锁定
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后 就不考虑依赖的声明顺序或者依赖的路径,已锁定的版本为准添加到工程中,这个方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二部:在dependencies标签中声明需要导入的maven坐标
在dependencyManagement标签中锁定依赖的版本,并不会真正的将jar包导入到项目中,只是对这些jar的版本经行锁定。项目中使用了哪些jar包,还需要在dependcies中经行声明。
如下图所示
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
在dependencies标签中声明需要导入的maven坐标,
<dependencies>
<!--由于在前面已经在dependencyManagement标签中锁定了依赖jar包的版本,
后面需要导入依赖的时只需要指定groupId和artifactild,无须再指定verison-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
Maven build之pom.xml文件中的Build配置
- 使用maven构建的项目均可以直接使用maven build完成项目的编译测试打包,无需额外配置
- Maven是通过pom.xml来执行任务的,其中的build标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过build中配置的 plugin 来完成。当然plugin配置不是必须的,默认情况下,Maven 会绑定以下几个插件来完成基本操作
即在没有配置的情况下,执行mvn clean install时,maven会调用默认的plugin来完成编译打包操作,具体来讲,执行mvn clean install时会执行
maven-clean-plugin:2.5:clean (default-clean)
maven-resources-plugin:2.6:resources (default-resources)
maven-compiler-plugin:3.1:compile (default-compile)
maven-resources-plugin:2.6:testResources (default-testResources)
maven-compiler-plugin:3.1:testCompile (default-testCompile)
maven-surefire-plugin:2.12.4:test (default-test)
maven-jar-plugin:2.4:jar (default-jar)
maven-install-plugin:2.4:install (default-install)
等plugin
- 如果有需要可以针对各个 plugin 进行特殊配置,需要在pom.xml中的<plugins>标签中显示指定 plugin 和 属性配置。
POM.XML的build标签
在Maven的pom.xml文件中,Build相关配置包含两个部分,一个是<build>,另一个是<reporting>,这里我们只介绍<build>。
1.pom.xml中的两种build
在Maven的pom.xml文件中,存在如下两种<build>:
说明:
一种<build>被称为Project Build,即是<project>的直接子元素。另一种<build>被称为Profile Build,即是<profile>的直接子元素。
Profile Build包含了基本的build元素,而Project Build还包含两个特殊的元素,即各种<...Directory>和<extensions>。
2.Profile Build和Project Build的共有元素
1) 共用的基本build元素
示例如下:
说明:
- defaultGoal,执行构建时默认的goal或phase,如jar:jar或者package等
- directory,构建的结果所在的路径,默认为${basedir}/target目录
- finalName,构建的最终结果的名字,该名字可能在其他plugin中被改变
2) <resources>
资源往往不是代码,无需编译,而是一些properties或XML配置文件,构建过程中会往往会将资源文件从源路径复制到指定的目标路径。
<resources>给出各个资源在Maven项目中的具体路径。示例如下:
说明:
- resources,build过程中涉及的资源文件
- targetPath,资源文件的目标路径
- filtering,构建过程中是否对资源进行过滤,默认false
- directory,资源文件的路径,默认位于${basedir}/src/main/resources/目录下
- includes,一组文件名的匹配模式,被匹配的资源文件将被构建过程处理
- excludes,一组文件名的匹配模式,被匹配的资源文件将被构建过程忽略。同时被includes和excludes匹配的资源文件,将被忽略。
- filters,给出对资源文件进行过滤的属性文件的路径,默认位于${basedir}/src/main/filters/目录下。属性文件中定义若干键值对。在构建过程中,对于资源文件中出现的变量(键),将使用属性文件中该键对应的值替换。
- testResources,test过程中涉及的资源文件,默认位于${basedir}/src/test/resources/目录下。这里的资源文件不会被构建到目标构件中
3) <plugins>
<plugins>给出构建过程中所用到的插件。
说明:
- groupId
- artifactId
- version
- extensions,是否加载该插件的扩展,默认false
- inherited,该插件的configuration中的配置是否可以被(继承该POM的其他Maven项目)继承,默认true
- configuration,该插件所需要的特殊配置,在父子项目之间可以覆盖或合并
- dependencies,该插件所特有的依赖类库
- executions,该插件的某个goal(一个插件中可能包含多个goal)的执行方式。一个execution有如下设置:
- id,唯一标识
- goals,要执行的插件的goal(可以有多个),如<goal>run</goal>
- phase,插件的goal要嵌入到Maven的phase中执行,如verify
- inherited,该execution是否可被子项目继承
- configuration,该execution的其他配置参数
4) <pluginManagement>
在<build>中,<pluginManagement>与<plugins>并列,两者之间的关系类似于<dependencyManagement>与<dependencies>之间的关系。<pluginManagement>中也配置<plugin>,其配置参数与<plugins>中的<plugin>完全一致。只是,<pluginManagement>往往出现在父项目中,其中配置的<plugin>往往通用于子项目。子项目中只要在<plugins>中以<plugin>声明该插件,该插件的具体配置参数则继承自父项目中<pluginManagement>对该插件的配置,从而避免在子项目中进行重复配置。
3. Project Build特有的<...Directory>
往往配置在父项目中,供所有父子项目使用。示例如下:
目录可以使用绝对路径,如示例所示。如果使用相对路径,则所有的相对路径都是在${basedir}目录下。
4. Project Build特有的<extensions>
<extensions>是执行构建过程中可能用到的其他工具,在执行构建的过程中被加入到classpath中。
也可以通过<extensions>激活构建插件,从而改变构建的过程。
通常,通过<extensions>给出通用插件的一个具体实现,用于构建过程。
<extensions>的使用示例如下:
==================================================================
******************************
maven默认的输入输出目录
************************************
==================================================================
构建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目录中。
当是web项目时,会在target下生成myproject目录,myproject是你的项目名
src/main/webapps
这个目录中的文件会被复制到target/myProject目录中
target/classes
默认会把这个目录中的所有内容复制到target/myProject/WEB-INF/classes目录中
Dependency
默认会将项目的依赖复制到target/myProject/WEB-INF/lib
Maven学习 --- <distributionManagement>
在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次。我们知道,maven的依赖管理是基于版本管理的,对于发布状态的artifact,如果版本号相同,即使我们内部的镜像服务器上的组件比本地新,maven也不会主动下载的。如果我们在开发阶段都是基于正式发布版本来做依赖管理,那么遇到这个问题,就需要升级组件的版本号,可这样就明显不符合要求和实际情况了。但是,如果是基于快照版本,那么问题就自热而然的解决了,而maven已经为我们准备好了这一切。
maven中的仓库分为两种,snapshot快照仓库和release发布仓库。snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),如下:
<groupId>cc.mzone</groupId>
<artifactId>m1</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
maven会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。如果是快照版本,那么在mvn deploy时会自动发布到快照版本库中,而使用快照版本的模块,在不更改版本号的情况下,直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。如果是正式发布版本,那么在mvn deploy时会自动发布到正式版本库中,而使用正式版本的模块,在不更改版本号的情况下,编译打包时如果本地已经存在该版本的模块则不会主动去镜像服务器上下载。
所以,我们在开发阶段,可以将公用库的版本设置为快照版本,而被依赖组件则引用快照版本进行开发,在公用库的快照版本更新后,我们也不需要修改pom文件提示版本号来下载新的版本,直接mvn执行相关编译、打包命令即可重新下载最新的快照库了,从而也方便了我们进行开发。
接下来要介绍的是如何在项目中应用snapshot和release库,应用snapshot和release库达到不同环境下发布不同的版本的目的,首先看一个pom文件的定义:pom.xml文件添加distributionManagement节点
<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>
<groupId>net.aty.mybatis</groupId>
<artifactId>mybatis-demo</artifactId>
<packaging>jar</packaging>
<version>${project.release.version}</version>
<name>mybatis-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.release.version>0.1-SNAPSHOT</project.release.version>
</properties>
<profiles>
<profile>
<id>release</id>
<properties>
<project.release.version>0.1</project.release.version>
</properties>
</profile>
</profiles>
<!-- 使用分发管理将本项目打成jar包,直接上传到指定服务器 -->
<!--定义snapshots库和releases库的nexus地址-->
<distributionManagement>
<!--正式版本-->
<repository>
<!-- nexus服务器中用户名:在settings.xml中<server>的id-->
<id>nexus-releases</id>
<!-- 这个名称自己定义 -->
<name>Nexus Release Repository</name>
<url>
http://172.17.103.59:8081/nexus/content/repositories/releases/
</url>
</repository>
<!--快照-->
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<url>
http://172.17.103.59:8081/nexus/content/repositories/snapshots/
</url>
</snapshotRepository>
</distributionManagement>
</project>
首先我们看到pom文件中version的定义是采用占位符的形式,这样的好处是可以根据不同的profile来替换版本信息,比如maven默认是使用0.1-SNAPSHOT作为该模块的版本。
1、如果在发布时使用mvn deploy -P release 的命令,那么会自动使用0.1作为发布版本,那么根据maven处理snapshot和release的规则,由于版本号后不带-SNAPSHOT故当成是正式发布版本,会被发布到release仓库;
2、如果发布时使用mvn deploy命令,那么就会使用默认的版本号0.1-SNAPSHOT,此时maven会认为是快照版本,会自动发布到快照版本库。
在distributionManagement段中配置的是snapshot快照库和release发布库的地址,我这里是采用nexus作为镜像服务器。对于版本库主要是id和url的配置,配置完成后就可以通过mvn deploy进行发布了,当然了,如果你的镜像服务器需要用户名和密码,那么还需要在maven的settings.xml文件中做如下配置:
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
< repository >节点下的< id >对应setting.xml文件中的server的id
<!--maven连接nexus需要验证用户名和密码-->
<server>
<id>yang</id>
<username>admin</username>
<password>admin123</password>
</server>
上传正式版本,pom.xml文件version中不能有SNAPSHOT,快照版本才有
<groupId>com.yang</groupId>
<artifactId>shade-plugin</artifactId>
<version>0.0.1</version>
<!-- <version>0.0.1-SNAPSHOT</version> -->
注意这里配置的server的id必须和pom文件中的distributionManagement对应仓库的id保持一致,maven在处理发布时会根据id查找用户名称和密码进行登录和文件的上传发布。
我们这里通过profile的定义就可以在发布灵活切换snapshot快照版本和release正式版本了,在被依赖的组件中也可以使用profile来定义在开发阶段使用快照库,在发布阶段使用正式库的功能,只需要在不同的profile中覆盖默认的properties属性值即可。