Maven 类加载指南

这是 Maven 中类加载器层次结构的描述。

概述

  • 系统类加载器
  • 核心类加载器
  • 插件类加载器
  • 自定义类加载器

1.系统类加载器

Maven 使用我们创建类加载器图的Plexus Classworlds类加载框架。如果您查看您的${maven.home}/boot目录,您将看到一个 JAR,它是我们用来引导类加载器图的 Classworlds JAR。Classworlds JAR 是Java 的唯一元素,CLASSPATHClassworlds 然后构建Classworlds 术语中的其他类加载器或领域。

像这样的 Ant 脚本将显示系统类加载器的内容:

    <target name="info">
      <echo>java.class.path=${java.class.path}</echo>
    </target>

2.核心类加载器

图下方的第二个类加载器包含 Maven 的核心需求。更准确地说,核心类加载器的库位于${maven.home}/lib. 一般来说,这些只是 Maven 库,例如MavenProject属于这个类加载器的实例。我们希望将来进一步将它们分离为 Maven API,并根据系统要求在运行时选择实现。

您可以通过扩展向这个类加载器添加元素。它们被加载到与当前项目和后续项目的 Maven 核心和所有插件相同的位置${maven.home}/lib,因此可以使用(将来,我们计划从后续项目中删除它)。

3.插件类加载器

之后,每个插件都有自己的类加载器,它是 Maven 核心类加载器的子类。这个类加载器中的类取自插件依赖列表中的依赖。

plugins/plugin用户可以通过将依赖项添加到项目部分中的插件来向此类加载器添加依赖项pom.xml。这是一个添加ant-nodeps到 Antrun 插件的插件类加载器的示例,从而可以使用附加/可选的 Ant 任务:

            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>1.3</version>
              <dependencies>
                <dependency>
                  <groupId>org.apache.ant</groupId>
                  <artifactId>ant-nodeps</artifactId>
                  <version>1.7.1</version>
                </dependency>
              </dependencies>
              ...
            </plugin>

插件可以通过表达式检查其有效的运行时类路径,${plugin.artifacts}或者${plugin.artifactMap}分别拥有从PluginDescriptor.

请注意,插件类加载器既不包含当前项目的依赖项,也不包含其构建输出。MavenProject相反,插件可以结合Mojo API 规范requiresDependencyResolution中的mojo 注释查询项目的编译、运行时和测试类路径。例如,标记 mojo使其能够查询当前项目的运行时类路径,从中可以创建更多的类加载器。@requiresDependencyResolution runtime

当一个构建插件被执行时,线程的上下文类加载器被设置为插件类加载器。

4.自定义类加载器

插件可以根据自己的判断自由创建更多的类加载器。例如,一个插件可能想要创建一个结合了插件类路径和项目类路径的类加载器。

重要的是要了解插件类加载器无法从任何这些自定义类加载器加载类。一些工厂模式要求这样做。在这里,您必须将类添加到插件类加载器,如前所示。