Maven的约定、插件和仓库

1,274 阅读5分钟

Maven 是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。它是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。

约定

Maven 使用约定优于配置的原则,提倡使用一个共同的标准目录结构。

在了解这些之前,我都一直认为 ${basedir}/src/main/java 是java项目的既有约定,而非maven的约定大于配置。

目录作用
${basedir}存放pom.xml和所有的子目录
${basedir}/src/main/java项目的java源代码
${basedir}/src/main/resources项目的资源,比如说property文件,springmvc.xml,application.yml
${basedir}/src/test/java项目的测试类,比如说Junit代码
${basedir}/src/test/resources测试用的资源
${basedir}/src/main/webapp/WEB-INFweb应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面
${basedir}/target打包输出目录
${basedir}/target/classes编译输出目录
${basedir}/target/test-classes测试编译输出目录
Test.javaMaven只会自动运行符合该命名规则的测试类
~/.m2/repositoryMaven默认的本地仓库目录位置

插件

Maven 有以下三个标准的生命周期:

  • clean:项目清理的处理
  • default(或 build):项目部署的处理
  • site:项目站点文档创建的处理 每个生命周期中都包含着一系列的阶段(phase)。这些 phase 就相当于 Maven 提供的统一的接口,然后这些 phase 的实现由 Maven 的插件来完成。

我们在输入 mvn 命令的时候 比如 mvn clean,clean 对应的就是 Clean 生命周期中的 clean 阶段, clean 的具体操作是由 maven-clean-plugin 来实现的。

Maven 实际上是一个依赖插件执行的框架,每个任务实际上是由插件完成。在默认情况下,Maven 会绑定默认插件来完成基本操作。

pluginfunctionlife cycle phase
maven-clean-plugin清理上一次执行创建的目标文件clean
maven-resources-plugin处理源资源文件和测试资源文件resources,testResources
maven-compiler-plugin编译源文件和测试源文件compile,testCompile
maven-surefire-plugin执行测试文件test
maven-jar-plugin创建 jarjar
maven-install-plugin安装 jar,将创建生成的 jar 拷贝到 .m2/repository 下面install
maven-deploy-plugin发布 jardeploy

如果针对各个 plugin 有特殊配置的话,需要显示指定 plugin 和 属性配置。例如,bulid

     <build>
         <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
         </plugins>
    </build>

仓库

Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。

Maven 仓库有三种类型:

  • 本地(local)
  • 中央(central)
  • 远程(remote)

本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。Maven 本地仓库默认被创建在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。

中央仓库,是由 Maven 社区提供的仓库,其中包含了大量常用的库。中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。

远程仓库,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。

Maven 依赖搜索顺序

当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:

  • 步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
  • 步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中以备将来引用。
  • 步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
  • 步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。

关于配置远程仓库

在pom.xml中使用repositories标签来配置maven项目的远程仓库。例如:

<repositories>  
        <repository>  
            <id>alimaven</id>  
            <name>aliyun maven</name>  
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
            <releases>  
            <!-- 可以从这个仓库下载releases版本的构件-->
                <enabled>true</enabled>  
            </releases>  
            <snapshots>  
            <!-- 不要从这个仓库下载snapshot版本的构件-->
                <enabled>false</enabled>  
            </snapshots>  
        </repository>  
</repositories>

关于版本号

菜鸟网站关于maven版本的一则评论:

1、Snapshot 版本代表不稳定、尚处于开发中的版本。

2、Release 版本则代表稳定的版本。

3、什么情况下该用 SNAPSHOT?

协同开发时,如果 A 依赖构件 B,由于 B 会更新,B 应该使用 SNAPSHOT 来标识自己。这种做法的必要性可以反证如下:

a. 如果 B 不用 SNAPSHOT,而是每次更新后都使用一个稳定的版本,那版本号就会升得太快,每天一升甚至每个小时一升,这就是对版本号的滥用。 b.如果 B 不用 SNAPSHOT, 但一直使用一个单一的 Release 版本号,那当 B 更新后,A 可能并不会接受到更新。因为 A 所使用的 repository 一般不会频繁更新 release 版本的缓存(即本地 repository),所以B以不换版本号的方式更新后,A在拿B时发现本地已有这个版本,就不会去远程Repository下载最新的 B

4、 不用 Release 版本,在所有地方都用 SNAPSHOT 版本行不行?

不行。正式环境中不得使用 snapshot 版本的库。 比如说,今天你依赖某个 snapshot 版本的第三方库成功构建了自己的应用,明天再构建时可能就会失败,因为今晚第三方可能已经更新了它的 snapshot 库。你再次构建时,Maven 会去远程 repository 下载 snapshot 的最新版本,你构建时用的库就是新的 jar 文件了,这时正确性就很难保证了。

参考:

www.runoob.com/maven/maven…

www.manongjc.com/detail/7-se…

www.jianshu.com/p/977b71e28…