《Maven权威指南》学习札记(二)

《Maven权威指南》学习笔记(二)

1.POM
  1. POM是Maven中一个项目的描述性陈述;也是当Maven构建项目的时候需要理解的一份“地图”
  2. 我们已经确定了POM是描述性和声明性的,它不像Ant或者Make那样提供显式的指令,我们也注意到POM的概念不是 特定于Java的
  3. 超级POM:它是Maven安装的一部分,可以在/usr/local/maven/lib中的maven-2.0.9-uber.jar文件中找到。如果       你看一下这个JAR文件,你会看到在包org.apache.maven.project下看到一个名为pom-4.0.0.xml的文件
     1. 默认的超级POM定义了一个单独的远程Maven仓库,该配置可以通过一个自定义的        settings.xml文件来覆盖.            注意这个默认的超级POM关闭了从*Maven仓库下载snapshot构件的功能
     2. 默认的插件仓库就是这个*仓库。Snapshot被关闭了,而且更新策略被设置成了“从不”,这意味着Maven将永            远不会自动更新一个插件,即使新版本的插件发布了。
     3. build元素设置Maven标准目录布局中那些目录的默认值
     4. 从Maven 2.0.9开始,超级POM为核心插件提供了默认版本
     5. 所有的Maven POM都继承自超级POM
  4. Maven开始于超级POM,然后使用一个或多个父POM覆盖默认配置,最后使用当前项目的POM来覆盖之前生成的配         置结果。最后你得到了一个混合了各个POM配置的有效POM。如果你想要查看项目的有效POM,你需要运行Maven         Help插件的effective-pom目标
  5. 项目版本
     1. Maven中的版本包含了以下部分:主版本,次版本,增量版本,和限定版本号
     2. 限定版本用来标识里程碑构建:alpha和beta发布,限定版本通过连字符与主版本,次版本或增量版本隔离
     3. 如果你的版本号与格式<主版本>.<次版本>.<增量版本>-<限定版本>相匹配,它就能被正确的比较,这种比较基于            主版本,次版本,和增量版本的数值,如果不标准,就会使用字符串进行比较.
     4. Maven会将限定版本后面的数字认作一个构建版本.但构建版本的解析还是使用字符串进行比较.可以使用“alpha-              02”和“alpha-10”来解决
     5. 如果一个版本包含字符串“SNAPSHOT”,Maven就会在安装或发布这个组件的时候将该符号展开为一个日期和时间          值,转换为UTC(协调世界时)(没试过)
     6. LATEST是指某个特定构件最新的发布版或者快照版(snapshot),最近被部署到某个特定仓库的构件。RELEASE是          指仓库中最后的一个非快照版本.如果你处于软件开发过程中,你可能想要使用RELEASE或者LATEST,这么做十分          方便,你也不用为每次一个第三方类库新版本的发布而去更新你配置的版本号。但当你发布软件的时候,你总是应该          确定你的项目依赖于某个特定的版本

   6. 属性引用
     1. 一个POM可以通过一对大括弧和前面一个美元符号来包含 对属性的引用
     2. Maven提供了三个隐式的变量,可以用来访问环境变量,POM信息,和Maven Settings
        1. env:env.*   环境变量如PATH和M2_HOME可以使用env.*前缀来引用
        2. project:你可以使用点标记(.)的路径来引用POM元素的值,如    ${project.artifactId}
        3.settings:例如,${settings.offline}会引用~/.m2/settings.xml文件中offline元素的值
     3. 你还可以引用系统属性,以及任何在Maven POM中和构建profile中自定义的属性组
        1. Java系统属性:所有可以通过java.lang.System中getProperties()方法访问的属性都被暴露成POM属性
        2. 我们还可以通过pom.xml或者settings.xml中的properties元素设置自己的属性,或者还可以使用外部载入的文             件中属性
   7. 项目依赖
      1. 依赖范围
          1. compile(编译范围).compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范               围依赖在所有的classpath中可用,同时它们也会被打包
          2. provided(已提供范围).当你的开发过程只有在编译和测试时需要一个类库,而该类库在运行的时候由容器提                 供,那么你就需要使用已提供范围的依赖.已提供范围的依赖在编译classpath(不是运行时)可用。它们不是传               递性的,也不会被打包。
          3. runtime(运行时范围).runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要
          4. test(测试范围).在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用
          5. system(系统范围)system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件                 的路径


2. 可选依赖(使用不多,不推荐)


3. 依赖版本界限
    1. (, )不包含量词
    2. [, ]包含量词
    3. 在逗号前面或者后面的版本不是必须的,这种空缺意味着正无穷或者负无穷
    4. 传递性依赖:其中的”传递性依赖和范围”有点绕,待实际需要了解时再做进一步了解.
    5. 冲突解决
        1. 排除一个传递性依赖
        2. 排除并替换一个传递性依赖
    6. 依赖管理
        1. Maven在dependencyManagement元素中为你提供了一种方式来统一依赖版本号,使用pom.xml中的                       dependencyManagement元素能让你在子项目中引用一个依赖而不用显式的列出版本号
        2. 如果子项目定义了一个版本,它将覆盖顶层POM的dependencyManagement元素中的版本
        3. 顶层POM中的依赖管理与在一个广泛共享的父POM中定义一个依赖是不同的:所有依赖都会被继承。如果mysql-               connector-java在顶层父项目中被作为一个依赖列出,这个层次中的所有项目都将引用该依赖。为了不添加一些             不必要的依赖,使用dependencyManagement能让你统一并集中化依赖版本的管理,而不用添加那些会被所有             子项目继承的依赖
    7. 项目关系
       1. 你应该避免在artifactId中使用它。因为在解析一个完整限定名字至子模块的时候,这会引发问题
       2. 坐标:groupId,artifactId,和version.还有第四个,也是最少用到的限定符:classifier
       3. 多模块项目:
          1. 多模块项目是那些包含一系列待构建模块的项目。一个多模块项目的打包类型总是pom,很少生成一个构件。一               个模块项目的存在只是为了将很多项目归类在一起,成为一个构建


4. 项目继承:
    1. Maven假设父POM在本地仓库中可用,或者在当前项目的父目录(../pom.xml) 中可用。如果两个位置都不可用,默         认行为还可以通过relativePath元素被覆盖


5. POM最佳实践
    1. 依赖归类:如果你有一组逻辑上归类在一起的依赖。你可以创建一个打包方式为pom项目来将这些依赖归在一起.当你         添加这个项目作为一个依赖,不要忘了指定依赖类型为pom(<type>pom</type>)
    2. 多模块 vs. 继承.多模块构建用来将模块聚集到一个单独的构建中,父子关系更多的是处理一个特定项目的定义.介绍了         两个例子,它们都综合运用了多模块和继承,这两个例子的思想各有不同,要好好研究