上一篇《 Maven基础教程之生命周期 》中也讲到了,Maven中通过模板方法这样的设计模式,生命周期只“立牌坊”,而实际上是插件在背后默默的奉献着。也就是说,在Maven中,真正的完成生命周期中那些阶段该干的活,都是由插件来做的。所以,从上面的描述,大家也能感受到Maven中插件的重要性了;插件非常重要,所以它的知识点肯定也少不了,对吧;然而,我的这篇关于插件的文章,我并不打算长篇大论的铺开来将Maven中的插件,因为我觉的有些东西,并不是那样的重要,所以,这篇关于插件的文章,点到为止,意会即可!
在继续下面的总结之前,我们需要先来理解“插件目标”这个概念。根据我们的开发经验,在开发一个软件时,这个软件肯定会包含很多的功能,并不会一个功能搞一个软件;同理,Maven中的插件也是这样的,比如下图所示:
而这里的每一个功能就对应一个插件目标。比如 maven-dependency-plugin
插件有十多个目标,每个目标对应一个功能。在《Maven基础教程之依赖》中讲到的 dependency:list
、 dependency:tree
和 dependency:analyze
这些都是插件目标,这是一种通用的写法,冒号前面是插件前缀,冒号后面是该插件的目标。
说完了插件目标,那这个插件目标到底如何使用呢?上一篇说了生命周期,这个生命周期和插件是相互独立存在的,如果需要插件完成生命周期对应阶段的任何,那就需要将生命周期与插件相互绑定,也就是说需要将生命周期的阶段与插件的目标相互绑定,这样才能完成某个具体的构建任务。
就如上图所示,default生命周期的compile阶段与maven-compiler-plugin插件的compile插件目标,到时候,就由compile插件目标完成default生命周期的compile阶段对应的实际操作。
关于插件绑定,主要分为内置绑定和自定义绑定两大类。
自定义绑定
为了能补充内置绑定的不足,完成更多个性化的任务,Maven社区的大牛开发了很多的插件,当然了,我们自己也可以开发,后面会讲到的。那这些插件如何和Maven的生命周期的阶段进行绑定呢,这就是我们要说的自定义绑定。下面我们通过一个例子来说明自定义绑定:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.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.jellythink.HelloWorld.App</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
在POM的 build
元素下的 plugins
子元素中声明插件的使用,插件在Maven中同其它包一样,也是作为独立的构建存在,所以也需要通过指定 groupId
、 artifactId
和 version
这三个坐标元素去仓库中定位插件。除了基本的插件坐标声明外,还有插件执行配置, executions
下每个 execution
子元素可以用来配置执行一个任务。上述例子中通过 phase
配置,将其绑定到 package
生命周期阶段上,再通过 goals
配置指定要执行的插件目标,这样自定义插件绑定就完成了。
执行 mvn clean install
命令,我们就可以看到这样的输出:
[INFO] --- maven-shade-plugin:3.2.1:shade (default) @ hello-world --- [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing E:/Code/Spring/helloworld/target/hello-world-1.0-SNAPSHOT.jar with E:/Code/Spring/helloworld/target/hello-world-1.0-SNAPSHOT-shaded.jar
可以看到执行了maven-shade-plugin插件的shade插件目标。
有的时候,你会看到有的插件不通过 phase
元素配置生命周期阶段,插件目标也能够绑定到生命周期中去。这个时候也不要惊讶,这主要是很多插件的目标在编写时已经定义了默认绑定阶段,我们可以通过 maven-help-plugin
查看插件的详细信息,了解插件目标的默认绑定阶段。执行 mvn help:describe -Dplugin=org.apache.maven.plugins:maven-shade-plugin:3.2.1 -Ddetail
就可以看到插件的完整信息,比如这个插件有几个插件目标,有哪些参数,默认绑定阶段等,通过查找 Bound to phase: package
,我们就可以看到默认绑定到哪个阶段。
我们在实现一个功能时,也会想着通过传递参数来实现更强大的功能。Maven插件也是这样的,我们可以配置插件目标的参数,满足我们对插件更加个性化的要求。对于插件的参数配置,有以下两种常用方式:
mvn clean install -Dmaven.test.skip=true
这个就是典型的通过命令行进行插件配置, maven.test.skip
是maven-surefire-plugin提供的一个参数,我们通过命令行传入一个true参数,表示跳过执行测试。
参数 -D
是Java自带的,其功能是通过命令行设置一个Java系统属性。Maven简单的重用了该参数。
通过POM文件进行插件全局配置
比如有些参数配置,从项目创建到项目发布都不会改变,或者基本上很少改变。对于这种场景,就更适合通过POM文件进行插件配置。比如以下的配置我们经常在一些项目中看到:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build>
这样就是一个全局的配置,也就是说,所有使用该插件目标的任务,都会使用这些配置。再回头看看上面插件绑定中自定义绑定里的那个例子,那个参数就是插件特有的参数,我们就可以通过参数实现一个不一样的功能。
Maven中最后一个核心概念终于总结完了。集齐了Maven中坐标、仓库、依赖、生命周期和插件这五大核心概念,应该就对Maven有一个比较全面的理解和认识了。这篇对Maven中的插件进行了比较全面的理解,当然了还有一些用的很少的知识点,或者我认为即使你不知道这些知识点也不会影响你对Maven插件的理解,在这里没有进行总结,如果你感兴趣,也可以自己阅读以下《Maven实战》这本书,你也许会有不同的收获。Maven的插件总结就到此完毕,接下来的文章将偏重于Maven的使用实战,感谢大家的一路支持,我们下一篇再见~祝好!
果冻想,认真玩技术的地方。
2019年4月17日,于内蒙古呼和浩特。