Maven面试题

《林老师带你学编程》知识星球是由多个工作10年以上的一线大厂开发人员联合创建,希望通过我们的分享,帮助大家少走弯路,可以在技术的领域不断突破和发展。

🔥 具体的加入方式:

Maven 是强大的构建工具,能够帮我们自动化构建过程–清理、编译、测试、打包和部署。比如测试,我们无需告诉 maven 如何去测试,只需遵循 maven 的约定编写好测试用例,当我们运行构建的时候,这些测试就会自动运行。

Maven 不仅是构建工具,还是一个依赖管理工具和项目信息管理工具。它提供了中央仓库,能帮助我们自动下载构件。

# 配置

配置用户范围 settings.xml。M2_HOME/conf/settings.xml 是全局范围的,而~/.m2/settings.xml 是用户范围的。配置成用户范围便于 Maven 升级。若直接修改 conf 目录下的 settings.xml,每次 Maven 升级时,都需要直接 settings.xml 文件。

# 入门

# 编写测试代码

# 添加 junit 依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

maven 会自动访问中央仓库,下载 junit 依赖。scope 为 test 表明依赖只对测试有效,即测试代码中的 import JUnit 代码没有问题,而主代码中使用 import JUnit 代码,则会产生编译错误。

# 编译

主类 HelloWorld

public class HelloWorld {
    public String sayHello() {
        return "Hello world";
    }
    public static void main(String[] args) {
        System.out.println(new HelloWorld().sayHello());
    }
}

编译代码:mvn clean compile

clean 清理输出目录/target,compile 编译项目主代码。

# 测试代码

public class HelloWorldTest {
    @Test
    public void testHelloWord() {
        HelloWorld hw = new HelloWorld();
        hw.sayHello();
    }
}

# 执行测试

mvn clean test

测试结果:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.tyson.test.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.117 sec

# 打包和安装

打包:mvn clean package 将项目代码打包成 jar 包,位于/target 目录。

安装:mvn clean install,将项目输出的 jar 包安装到 maven 本地库,这样其他 maven 项目就可以直接引用这个 jar 包。

默认打包生成的 jar 不能直接运行,为了生成可运行的 jar 包,需要借助 maven-shade-plugin。

    <build>
        <finalName>HelloWorld</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.tyson.maven.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

执行顺序:compile->test->package->install

# 依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.7</version>
    <scope>test</scope>
</dependency>

  • scope:依赖的范围
  • type:依赖的类型,jar 或者 war
  • exclusions:用来排除传递性依赖

# 依赖范围 scope

maven 在编译、测试和运行项目时会使用不同的 classpath(编译classpath、测试 classpath、运行 classpath)。依赖范围就是用来控制依赖和这三种 classpath 的关系。maven 中有以下几种依赖范围:

  • compile:默认值,使用该依赖范围的 maven 依赖,在编译、测试和运行时都需要使用该依赖
  • test:只对测试 classpath 有效,在编译主代码和运行项目时无法使用此类依赖。如 JUnit 只在编译测试代码和运行测试的时候才需要此类依赖
  • provided:已提供依赖范围。对于编译和测试 classpath 有效,但在运行时无效。如 servlet-api,编译和测试时需要该依赖,但在运行项目时,由于容器已经提供此依赖,故不需要 maven重复引入
  • runtime:运行时依赖范围。对于测试和运行 classpath 有效,但在编译主代码时无效。如 JDBC 驱动实现,项目主代码的编译只需要 JDK 提供的 JDBC接口,只有在测试和运行时才需要实现 JDBC 接口的具体实现
  • system:系统依赖范围
  • import:导入依赖范围 import 导入依赖管理

# 传递性依赖

假如项目 account 有一个 compile 范围的 spring-core 依赖,而 spring-core 有一个 compile 范围的 common-logging 依赖,那么 common-logging 就会成为 account 的 compile 范围依赖,common-logging 是 account 的一个传递性依赖。maven 会直接解析各个直接依赖的 POM,将那些必要的间接依赖,以传递性依赖的形式引入到项目中。

spring-core 是 account 的第一直接依赖,common-logging 是 spring-core 的第二直接依赖,common-logging 是 account 的传递性依赖。第一直接依赖的范围和第二直接依赖的范围共同决定了传递性依赖的范围。下表左边是第一直接依赖的范围,上面一行是第二直接依赖的范围,中间部分是传递依赖的范围

# 排除依赖

查看更多

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

滚动至顶部