157

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

4

8 回答 8

262

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

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

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

你的场景也是如此。您必须使用 spring-plugin 来执行一些 spring 可执行文件 [我不确定 spring-plugin 用于什么。我只是在这里猜测]。但是您需要依赖项来执行这些可执行文件。并且 Junit 被标记为依赖项,因为它被 surefire-plugin 用于执行单元测试。

所以,我们可以说,plugin 是一个执行任务的 Jar 文件,dependency 是一个提供执行任务的类文件的 Jar。

希望这能回答你的问题!

于 2012-08-09T12:54:50.050 回答
44

Maven 本身可以被描述为食物处理器,它有许多不同的单元可以用来完成不同的任务。这些单元称为插件。例如,编译您的项目 maven 使用maven-compiler-plugin, 运行测试 -maven-surefire-plugin等等。

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

于 2012-08-09T10:51:46.817 回答
35

插件和依赖是非常不同的东西,它们是互补的。

什么插件?

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

这些是 Maven 的核心。
Maven 执行的任何任务都是由 plugins 执行的
有两类插件:插件和插件buildreporting

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

根据命令行中指定的 maven 目标(例如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 工件/组件。

具体来说,大多数依赖项都是 jar(即库),但它们也可能是其他类型的档案:war、ear、test-jar、ejb-client ... 或者仍然是 POM 或 BOM。

在 pom.xml 中,可以在多个位置指定依赖项:<build><dependencies>part、dependencies managementpart 或仍在声明plugin!事实上,一些插件在执行过程中可能需要在类路径中有一些依赖项。这并不常见,但可能会发生。
以下是文档中的一个示例,该示例表明plugin并且dependency可以一起工作:

比如 Maven Antrun Plugin 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>

依赖项没有作为插件的阶段绑定来解决“何时”问题。
但它有一个对应物:范围

根据我们为它们定义的范围,应用程序确实可以在特定时间使用声明的依赖项。
scope是关于如何在项目中看到依赖项的核心概念。

默认范围是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>
于 2018-08-31T16:44:39.417 回答
11

如果你像我一样有前端背景,并且熟悉 Grunt 和 npm,可以这样想:

首先你会运行,比如说,npm install grunt-contrib-copy --save-dev. 这就像 maven 的<dependency></dependency>。它下载执行构建任务所需的文件。

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

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

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

当然,这不是一个精确的类比,但足够接近以帮助您理解它。

于 2015-09-20T14:41:41.020 回答
8

一线答案——基本了解

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

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

于 2020-04-29T11:48:05.720 回答
5

插件用于向Maven自身添加功能(如添加eclipse支持或SpringBoot支持Maven等)。您的源代码需要依赖项才能通过任何 Maven 阶段(compiletest例如)。如果JUnit由于测试代码基本上是您的代码库的一部分,并且您JUnit在测试套件中调用特定命令,并且这些命令未提供,Java SDK因此JUnit必须Maven在测试阶段出现,并且通过提及JUnit作为依赖项来处理在你的pom.xml文件中。

于 2015-08-20T14:33:38.933 回答
1

Maven 的核心是一个插件执行框架——根据正式和标准的紧凑定义。为了更清楚,您使用的命令就像maven-install/clean/compile/build etc创建/执行 jars,我们有时也手动运行。所以,你想要运行(或配置或执行)的东西,你基本上把它们放在 mavens pom 的依赖标签中,然后谁将运行这些依赖(环境设置所需)的答案就是插件。

        javac (compiler) dependency.java (dependency) 
于 2019-01-01T17:51:15.513 回答
1

插件是 Maven 的扩展,用于生成您的工件(例如,maven-jar-plugin 用于,您猜对了,从您编译的类和资源中制作一个 jar)。

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

插件和依赖

于 2019-10-29T09:16:47.063 回答