Java 之旅

中级02 - Java的包管理与Maven初步

2019-08-14  本文已影响0人  晓风残月1994

1. 包和类路径

这里说的包是一个更宽的概念, 可以理解为把许多 Java 的 package 和其中的类放在一起打的压缩包(.jar其实就是zip)。

JVM 的工作被设计地相当简单:
执行一个类的字节码,假如过程中碰到了新的类,就加载它。
去哪里找呢?
根据类(搜索)路径(Classpath)查找,也就是 -classpath/-cp参数。

但这存在一些问题:

2. Maven 之前的年代

2. 什么是包管理

你要使用的第三方类,要告诉 JVM 查找的路径,因此包管理的本质就是告诉 JVM 如何找到所需的第三方类库,以及成功地解决其中的冲突问题。

3. Maven—划时代的包管理

Convention over configuration 约定优于配置,Maven 远远不⽌是包管理⼯具。
Maven 的中央仓库,按照⼀定的约定存储包。Maven 的本地仓库默认位于~/.m2,下载的第三⽅包放在这⾥进⾏缓存。
Maven 按照约定为所有的包编号,⽅便检索:

Maven 会对传递性依赖进行自动管理,管理原则是:
绝对不允许最终的 classpath 出现同名不同版本的 jar 包

解决 Maven 的包冲突

当你看到如下异常时要考虑是否存在包冲突:

AbstractMethodError
NoClassDefFoundError
ClassNotFoundException
LinkageError

可以通过mvn dependency:tree在命令行中查看依赖树,或者在 IDEA 的 Maven 栏目中查看。

Maven 自动解决包冲突的原则:

手动解决 Maven 不能解决的包冲突问题:

<dependency>
    <groupId>com.github.xxx<groupId>
    <artifactId>test-library-a</artifactId>
    <version>0.1</version>
    <!-- test-library-c 被干掉了 -->
    <exclusions>
        <exclusion>
            <groupId>com.github.xxx<groupId>
            <artifactId>test-library-c</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Maven 依赖中的 scope

scope 用于在不同代码目录中隔离第三方依赖,选项有compile/test/provided等:

  <dependencies>
    <!-- testing -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.5.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

4. Maven—⾃动化构建⼯具

核心概念:坐标和依赖、生命周期、仓库、聚合和继承
《Maven实战》5、6、7、8章核心概念要看, 13、14、17、18章可以略读。

练习:实现语义化版本
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Version {
    /**
     * 请根据语义化版本的要求 https://semver.org/lang/zh-CN/ ,比较两个"语义化版本"
     *
     * <p>传入两个形如x.y.z的字符串,比较两个语义化版本的大小。如果version1小于version2,返回-1;如果version1大于
     * version2,返回1。如果二者相等,返回0。
     *
     * <p>注意,如果传入的字符串形如x,则其等价于x.0.0。 如果传入的字符串形如x.y,则其等价于x.y.0。
     *
     * @param version1 传入的版本字符串1,支持x/x.y/x.y.z,你可以假定传入的字符串一定是合法的语义化版本
     * @param version2 传入的版本字符串2,支持x/x.y/x.y.z,你可以假定传入的字符串一定是合法的语义化版本
     * @return -1/0/1 当version1 小于/等于/大于 version2时
     */

    private static List<String> stylizeVersion(String version) {
        List<String> vList = new ArrayList<>(Arrays.asList(version.split("\\.")));
        while (vList.size() < 3) {
            vList.add("0");
        }
        return vList;
    }

    public static int compare(String version1, String version2) {
        for (int i = 0; i < 3; i++) {
            int v1 = Integer.parseInt(stylizeVersion(version1).get(i));
            int v2 = Integer.parseInt(stylizeVersion(version2).get(i));
            if (v1 < v2) {
                return -1;
            } else if (v1 > v2) {
                return 1;
            }
        }
        return 0;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读