pom xml中的依赖项标签和插件标签之间的maven有什么区别?


118

我是Maven工具的新手,我使用Spring和Hibernate创建了一个项目,它们在pom.xml中配置为插件,但是JUnit在依赖项下被标记。我的问题是,一个作为插件,一个作为依赖项背后的逻辑是什么?

Answers:


213

插件和依赖项都是Jar文件。

但是它们之间的区别是,maven中的大多数工作都是使用插件完成的。而依赖项只是一个Jar文件,将在执行任务时将其添加到类路径中。

例如,您使用编译器插件来编译Java文件。您不能将编译器插件用作依赖项,因为这只会将插件添加到类路径中,并且不会触发任何编译。编译文件时要添加到类路径的Jar文件将被指定为依赖项。

您的情况也是如此。您必须使用spring-plugin执行一些spring可执行文件[我不确定spring-plugins的用途。我只是在这里猜测]。但是您需要依赖项来执行那些可执行文件。并且Junit被标记为依赖项,因为surefire插件将其用于执行单元测试。

因此,可以说,插件是一个执行任务的Jar文件,而依赖项是一个提供执行任务的类文件的Jar。

希望这能回答你的问题!


我可以告诉我执行的阶段和目标有什么区别吗?据我所知,这个阶段正在谈论行家的生命周期。但是为什么要再次瞄准呢?有什么提示吗?有时我看到人们把生命周期关键字作为目标... ??? (?。?)
taymedee

@taymedee这个SO问题描述了区别:stackoverflow.com/questions/16205778/…–
dev_feed

1
@ r981您的答案需要更清楚。这个答案是更好:stackoverflow.com/questions/26292073/...
数字无常

我认为此答案的遗漏之处在于:顶级依赖关系主要由您的工件而不是插件使用。
lfree

3
@MichaelPacheco,我的意思是,spring-plugin将执行执行一组代码的特定任务,这可能取决于某些库,这些库将由“ dependencies”指定。再举一个例子:您需要一个编译器来执行一段代码;在这里,您的编译器是一个插件,而您的代码是可执行文件。仅编译器就能执行任何代码,但是您的代码可能依赖于库,例如apache commons,这将是一个依赖项。只有在类路径中存在依赖项时,编译器才能编译代码。我希望现在很清楚。
r9891

37

Maven本身可以描述为食品加工机,它具有许多不同的单元,可用于完成不同的任务。这些单元称为插件。例如,要编译项目,maven使用maven-compiler-plugin,运行测试- maven-surefire-plugin等等。

关于Maven的依赖关系是项目依赖的打包的类。它可以是jar,war等。例如,如果您希望能够编写JUnit测试,则必须使用JUnit批注和类,因此必须声明您的项目依赖于JUnit。


感谢您的快速答复,对不起,但我仍然感到困惑,因为我知道JUnit也是一个框架,并且(hibernate,spring)也只在框架下,所以这意味着在某些情况下(hibernate,spring)也可以在依赖项标签中进行配置?我希望你能回答我的问题。
珊瑚2012年

是的,据我所知没有Spring Maven插件之类的东西。通常,Spring库(或Hibernate,JUnit或TestNG等)被声明为项目的依赖项。如果您不熟悉Maven,建议您读一非常好的书。
安德鲁·洛格维诺夫

@AndrewLogvinov-我有一个用于api自动化测试的多pom项目。其中一个maven项目具有自动化测试。项目pom的build部分只有一个插件-引用套件的maven surefire插件。整个构建标记已删除。你能告诉我这是什么意思吗?谢谢。
MasterJoe

15

插件和依赖项是完全不同的东西,它们是互补的。

什么是插件?

插件执行Maven构建的任务。这些未打包在应用程序中。

这些是Maven的心脏。
Maven执行的任何任务都由插件执行
有两种类型的插件:buildreporting插件

  • 构建插件将在构建期间执行,并且应在 <build/>在POM元素中。
  • 报告插件将在网站生成期间执行,并且应<reporting/在POM 的>元素中进行配置。

根据在命令行中指定(例如行家目标mvn cleanmvn clean packagemvn site),特定的生命周期将被用于和的插件目标的特定组将被执行。
有三个内置构建生命周期:defaultcleansite。在default生命周期处理你的项目部署中,clean生命周期把手伸出清洗,而site生命周期把手创建项目的网站上的文档。

插件目标可能绑定到特定生命周期的特定阶段。
例如maven-compiler-plugin,默认情况下,将compile目标绑定到生命周期阶段:compile
大多数Maven插件(核心插件和第三方插件)都倾向于使用约定而非配置。因此,这些通常将插件目标限制在特定阶段,以简化其使用。

那更整洁,更不容易出错:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
</plugin>

比:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <executions>
    <execution>
        <phase>compile</phase>
        <goals>
            <goal>compile</goal>
        </goals>
    </execution>
  </executions>
</plugin>

什么是依赖项?

依赖关系是在Maven构建期间类路径中所需的Maven工件/组件。
这些可以打包在应用程序中,但不一定打包(请参阅scope下文)。

大多数依赖项是jar,但也可能是其他类型的存档:war,ear,test-jar,ejb-client ...或仍然是POM或BOM。
的:在一个pom.xml,依赖性可以在多个位置指定<build><dependencies>部分,该dependencies management部分或仍然一个plugin声明!实际上,某些插件在执行期间可能需要在类路径中具有某些依赖项。这并不常见,但可能会发生。
这是文档中的一个示例,显示了plugindependency可以一起工作:

例如,Maven Antrun插件版本1.2使用Ant版本1.6.5,如果要在运行此插件时使用最新的Ant版本,则需要添加<dependencies>如下元素:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.2</version>
        ...
        <dependencies>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.1</version>
          </dependency>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-launcher</artifactId>
            <version>1.7.1</version>
          </dependency>
         </dependencies>
      </plugin>
    </plugins>
  </build>
  ...
</project>

在Maven中,依赖项以特定格式引用:
groupId:artifactId:packaging:classifier:version。通常不指定
分类器(可选)和包装(JAR默认情况下)。所以dependency声明中的通用格式是:groupId:artifactId:version
这是该<build><dependencies>部分中声明的依赖项的示例:

<build>
   <dependencies>
      <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-core</artifactId>
         <version>5.2.14.Final</version>
      </dependency>
   <dependencies>
</build>

与插件相反,依赖项具有作用域。
默认范围是compile。那是最普遍需要的范围(再次通过配置进行约定)。
compile范围意味着该依赖性在一个项目的所有类路径可用。

范围定义了应该在其中添加依赖项的类路径。例如,我们是在编译和运行时还是仅在测试编译和执行时需要它?

例如,我们先前将Hibernate定义为compile依赖项,因为我们在任何地方都需要它:源代码编译,测试编译,运行时等等。
但是,我们不希望测试库可以打包在应用程序中或在源代码中引用。 。因此,我们test为它们指定了范围:

<build>
   <dependencies>
     <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.1.0</version>
        <scope>test</scope>
     </dependency>
   <dependencies>
</build>

很好的解释!,由于我不熟悉Java设置依赖项,因此我仍然怀疑,我目前在IntelliJ中工作,并在尝试包括以下内容时创建了一个maven项目: webdriver-ie两个选项时,要么将其包含为pluginsdependency,我将两者都包括在内进行比较,并且观察到两者具有完全相同groupId的唯一区别是,它们plugins没有附带特定版本,而是dependency附带了0.6.685。您能否以通俗易懂的人(相对于本示例)来解释它,区别是什么,何时使用。有什么建议吗?
阿努

1
很难给出最准确的答案,而不会看到你的想法pom.xml。但是您应该感兴趣的是,在任何Maven版本中,都必须指定依赖性版本(在当前pom或父pom中,如果它是继承的依赖性)是必需的,而从Maven 3开始(可能是一个不好的主意),指定插件版本是可选的。Maven将使用Maven查找版本库中可用的最新版本。(1/2)
davidxxx '19

1
请注意,指定插件是一种不好的方法。随着时间的推移,它不能使您的构建可复制(cwiki.apache.org/confluence/display/MAVEN/…)。您应该在构建中看到警告。那么区别是什么呢 ?”。插件执行Maven构建的任务,而依赖项是构建期间类路径中所需的库(jar或其他)。如果您的项目构建在任何情况下都是相同的(使用库或插件方式),则意味着插件没有使用就变得无能为力。(2/2)
davidxxx

6

如果您来自像我这样的前端背景,并且熟悉Grunt和npm,请这样考虑:

首先,您将运行npm install grunt-contrib-copy --save-dev。这就像行家的<dependency></dependency>。它下载执行构建任务所需的文件。

然后,您将在Gruntfile.js中配置任务

copy: {
  main: {
    src: 'src/*',
    dest: 'dest/',
  },
}

这就像maven的<plugin>/<plugin>。您正在告诉构建工具如何处理npm /下载的代码<dependency></dependency>

当然,这不是一个确切的类比,但足够接近以帮助您将头缠住。


4

插件用于为其Maven自身添加功能(例如添加eclipse支持或SpringBootMaven等的支持)。由源代码所需要的依赖关系通过任何Maven的相位(compiletest例如)。如果JUnit由于测试代码基本上是代码库的一部分,并且您JUnit在测试套件中调用了特定命令而这些命令没有提供,那么在测试阶段Java SDKJUnit必须存在这些命令,Maven并通过提及JUnit为依赖项进行处理在您的pom.xml文件中。


1

Maven的核心是插件执行框架-根据正式和标准的紧凑定义。更清楚地说,您使用的命令类似于maven-install/clean/compile/build etc创建/执行jars,有时我们也手动运行它们。因此,要运行(或配置或执行)的事物基本上是将它们放在mavens pom的依赖项标签中,然后将答案插入谁来运行这些依赖项(对于环境设置是必需的)。

        javac (compiler) dependency.java (dependency) 

1

一线回答-基本理解

插件是您在执行Maven构建时使用的工具

依赖意味着您将在代码中使用的任何库的种类


0

插件是Maven的扩展,是用来生成工件的东西(例如,maven-jar-plugin用来从已编译的类和资源中创建jar)。

依赖项是您正在构建的应用程序在编译和/或测试和/或运行时所需的库。

插件和依赖

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.