Maven编译阶段和插件目标之间有什么区别?

时间:2019-11-24 16:35:54

标签: java maven maven-plugin

我正在学习Maven,我试图了解生命周期和插件之间的区别。例如,我有一个非常简单的Maven项目,如下所示:

import org.apache.commons.lang3.StringUtils;

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!!!! ");
        System.out.println(StringUtils.capitalize("hello world"));
    }
}

这是pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>guru.springframework</groupId>
    <artifactId>hello-world</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>auto-clean</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>clean</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

如果我使用以下命令:mvn compiler:compile,它将创建目标文件夹,并且在HelloWorld.class中,我看到以下内容:Decompiled .class file, bytecode version: 55.0 (Java 11)。因此它使用的是Java11。

现在,如果我将pom.xml中的Java版本更改为1.8,然后再次使用命令mvn compiler:compile,则会看到消息:Nothing to compile - all classes are up to date。并且在目标文件夹中,HelloWorld.class具有:Decompiled .class file, bytecode version: 55.0 (Java 11)。因此,在pom.xml中将Java更改为1.8后,它显示了Java 11。

然后,如果我使用命令mvn compile,则首先使用maven-clean-plugin (auto-clean),然后使用maven-resources-plugin (default-resources),然后使用maven-compiler-plugin (default-compiler),并显示以下消息:Changes detected - recompiling the module! 。并且在目标文件夹中,HelloWorld.class具有:Decompiled .class file, bytecode version: 52.0 (Java 8)。所以现在它使用Java 8。

所以我不明白为什么如果我使用命令mvn compiler:compile却不使用我在pom.xml中添加的auto-clean的原因。但是,如果我使用的是mvn compile,它将使用auto-clean。有人可以帮我理解吗?

而且我也不明白为什么我使用命令mvn clean却使用default-clean。但是,如果我使用命令mvn compile,它将使用auto-clean。任何反馈将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

阶段和插件目标之间的区别在于,阶段是不同插件目标执行的组。

请注意,当前执行之前处于生命周期中的所有阶段也将被执行,即执行compile阶段也会导致validateinitializegenerate-sources,{{1 }},process-sourcesgenerate-resources运行。


直接在命令行上指定插件目标时,忽略整个生命周期即可运行它。