架构师工具箱(二)Maven——Maven流行插件、手写自己的插件

写在前面:

  •     你好,欢迎关注!
  •     我热爱技术,热爱分享,热爱生活, 我始终相信:技术是开源的,知识是共享的!
  •     博客里面的内容大部分均为原创,是自己日常的学习记录和总结,便于自己在后面的时间里回顾,当然也是希望可以分享 自己的知识。如果你觉得还可以的话不妨关注一下,我们共同进步!
  •      个人除了分享博客之外,也喜欢看书,写一点日常杂文和心情分享,如果你感兴趣,也可以关注关注!
  •      公众号:傲骄鹿先生

目录

一、Maven流行插件

1、maven-assembly-plugin

2、maven-shade-plugin

3、maven-dependency-plugin

4、maven-compiler-plugin

5、maven-resources-plugin

6、maven-jar-plugin

7、maven-source-plugin

二、手写Maven插件

1.Maven 插件的命名规范

2.什么是 Mojo?

3.创建MoJo工程

4、测试自定义插件


一、Maven流行插件

Maven 中项目的构建生命周期只是 Maven 根据实际情况抽象提炼出来的一个统一标准和规范,是不能做具体事情的。也就是说,Maven 没有提供一个编译器能在编译阶段编译源代码。既然 Maven 不做具体事情,那具体事情由谁做呢?好的思想、创意,最终都需要在做具体事情的实践中执行才有结果。

所以 Maven 只是规定了生命周期的各个阶段和步骤,具体事情,由集成到 Maven 中的插件完成,就是由 maven-site-plugin 插件完成的。
Maven 在项目的构建过程中,只是在方向和步骤上面起到了管理和协调的作用。
Maven 在生命周期的每个阶段都设计了插件接口。用户可以在接口上根据项目的实际需要绑定第三方的插件,做该阶段应该完成的任务,从而保证所有 Maven 项目构建过程的标准化。当然,Maven 对大多数构建阶段绑定了默认的插件,通过这样的默认绑定,又简化和稳定了实际项目的构建。

Maven插件的基本概念能帮助我们理解maven的工作机制,但是高效的使用Maven避免不了使用插件,接来下就看一些常用的:

1、maven-assembly-plugin

该插件允许用户整合项目的输出,包括依赖,模块,网站文档和其他文档到一个单独的文档,即可用定制化打包。

创建的文档格式包括:zip, tar, tar.gz(tgz), gar.bz2(tbgz2), jar, dir,war 等等。四种预定义的描述器可用:bin, jar-with-dependencies, src, project.

(1)打包独立运行的jar文件

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <!-- 配置main方法入口程序 -->
                <mainClass>org.chench.Main</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

特别注意: 如果在项目中使用了Spring框架,在通过maven-assembly-plugin打包成独立可执行的jar包后,在执行时可能报如下错误:

Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace 

这其实是maven-assembly-plugin的一个BUG,解决方案:使用maven-shade-plugin插件进行打包。

(2)打包压缩文件

maven-assembly-plugin插件除了可以打包项目为可独立运行的jar文件,还可以将项目打包为压缩文件。

<!-- 部署打包: 通过maven-assembly插件压缩为tar包进行发布 -->
<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <!-- 配置执行器 -->
        <execution>
            <id>assembly</id>
            <!--绑定到package生命周期-->
            <phase>package</phase>
            <goals>
                <!--只运行一次-->
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <appendAssemblyId>false</appendAssemblyId>
        <attach>false</attach>
        <descriptors>
            <!--配置描述文件路径--> 
            <descriptor>src/main/assembly/assembly.xml</descriptor>
        </descriptors>
        <finalName>${project.name}-${project.version}</finalName>
        <outputDirectory>${basedir}/release</outputDirectory>
    </configuration>
</plugin>

assembly.xml配置

<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>distribution</id>
    <formats>
        <!-- 压缩包格式 -->
        <format>tar.gz</format>
        <!-- <format>zip</format> -->
    </formats>
    
    <!-- 打包文件参数配置 -->
    <fileSets>
        <!-- 脚本 -->
        <fileSet>
            <directory>${basedir}/src/main/bin</directory>
            <outputDirectory>bin</outputDirectory>
            <includes>
                <include>*.bat</include>
                <include>*.sh</include>
            </includes>
            <fileMode>0755</fileMode>
        </fileSet>
        
        <!-- sql文件 -->
        <fileSet>
            <directory>${basedir}/src/main/sql</directory>
            <outputDirectory>sql</outputDirectory>
            <includes>
                <include>*.sql</include>
            </includes>
        </fileSet>
        
        <!-- jdbc.properties, logback.xml -->
        <fileSet>
            <directory>${basedir}/src/main/resources/profiles/${profile.dir}</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>jdbc.properties</include>
                <include>logback.xml</include>
            </includes>
        </fileSet>
        
        <!-- INSTALL,README,change.log -->
        <fileSet>
            <directory>${basedir}</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>INSTALL</include>
                <include>README.md</include>
                <include>change.log</include>
            </includes>
        </fileSet>
        
        <!-- 日志目录 -->
        <fileSet>
            <directory>target</directory>
            <outputDirectory>logs</outputDirectory>
            <excludes>
                <exclude>**/*</exclude>
            </excludes>
        </fileSet>
        
        <!-- 临时目录 -->
        <fileSet>
            <directory>target</directory>
            <outputDirectory>temp</outputDirectory>
            <excludes>
                <exclude>**/*</exclude>
            </excludes>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>lib</outputDirectory>
            <excludes>
                <exclude>junit:junit</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
    
    <includeBaseDirectory>true</includeBaseDirectory>
    <baseDirectory>${project.name}-${project.version}</baseDirectory>
</assembly>

2、maven-shade-plugin

打包可独立运行的jar文件

<!-- 打包可执行jar文件 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>org.chench.Main</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

3、maven-dependency-plugin

通过该插件可以对被依赖组件进行复制,解压等一系列操作。

场景一: 在Maven多模块化项目中,可以使用maven-dependency-plugin将被依赖模块jar文件中class文件提取出来放在指定位置。

<!-- 将依赖模块的jar包文件提取出来放到指定位置 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>com.xxx</groupId>
                        <artifactId>xxx-xxx</artifactId>
                        <version>1.0.0</version>
                        <type>jar</type>
                        <includes>**/*.class</includes>
                        <overWrite>false</overWrite>
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

场景二:将scope为system的依赖jar包一起打包

<!-- 打包scope为system的jar包 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.0.2</version>
        <executions>
            <execution>
                <phase>prepare-package</phase>
                <goals>
                    <goal>copy-dependencies</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <includeScope>system</includeScope>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
</plugin>

场景三:将scope为system的依赖jar包中的class文件解压出来重新打包

<!-- 将scope为system的依赖jar包中的class文件解压出来重新打包 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.0.2</version>
    <executions>
        <execution>
            <id>unpack</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includeScope>system</includeScope>
        <outputDirectory>${project.build.directory}/classes</outputDirectory>
    </configuration>
</plugin>

4、maven-compiler-plugin

打包时设置编译参数。

<plugin>                                                                                                                                                                                                  
    <groupId>org.apache.maven.plugins</groupId>                                                                                               
    <artifactId>maven-compiler-plugin</artifactId>                                                                                            
    <version>3.1</version>                                                                                                                    
    <configuration>                                                                                                                                          
        <source>1.8</source> <!-- 源代码使用的JDK版本 -->                                                                                             
        <target>1.8</target> <!-- 需要生成的目标class文件的编译版本 -->                                                                                     
        <encoding>UTF-8</encoding><!-- 字符集编码 -->
        <skipTests>true</skipTests><!-- 跳过测试 -->                                                                                          
    </configuration>                                                                                                                          
</plugin>

5、maven-resources-plugin

maven默认使用该maven-resources-plugin资源文件,不需要明确配置。

<resources>
    <resource>
        <!-- 指定资源目录 -->
        <directory>src/main/resources</directory>
        <!-- 不打包指定类型的资源 -->
        <excludes>
            <exclude>**/*.svn</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources/profiles/${profile.dir}</directory>
        <includes>
            <include>*.properties</include>
        </includes>
    </resource>
</resources>

6、maven-jar-plugin

https://maven.apache.org/plugins/maven-jar-plugin/usage.html

使用该插件可以在打包jar文件时做一些事情,比如:定义MANIFEST.MF文件,过滤文件等。

<!-- 生成jar包时打包资源文件配置 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <excludes>
            <exclude>**/profiles/**</exclude>
            <exclude>**/jdbc.properties</exclude>
            <exclude>**/*.proto</exclude>
        </excludes>
    </configuration>
</plugin>

7、maven-source-plugin

https://maven.apache.org/plugins/maven-source-plugin/usage.html

打包项目源码。

<!-- 打包源码 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

二、手写Maven插件

Maven 作为一个优秀的项目管理工具,其插件机制为其功能扩展提供了非常大的便捷性。虽然说大多数情况下,我们可能不太会自己去编写 Maven 插件,但不排除在某些特殊的情况下,我们需要去完成一个自己的插件,来协助我们处理某些比较通用的事情。

1.Maven 插件的命名规范

按照官方建议,maven插件的命名建议为xxxx-maven-plugin,这样命名有两个好处

1、maven-xxxx-plugin为maven官方插件命名,使用这种命名方式可能侵权

2、自定义插件maven执行命令为mvn groupId:artifactId:goal,使用推荐命名方式,maven命令可以简化为mvn xxxx:goal

2.什么是 Mojo?

Mojo 就是Maven plain Old Java Object。每一个 Mojo 就是 Maven 中的一个执行目标(executable goal),而插件则是对单个或多个相关的 Mojo 做统一分发。一个 Mojo 包含一个简单的 Java 类。插件中多个类似 Mojo 的通用之处可以使用抽象父类来封装。

3.创建MoJo工程

1、创建maven工程,选择类型为mojo

2、指定groupId、artifactId、版本号

3.在pom文件中指定打包类型为maven-plugin

4、添加依赖

5、创建mojo实现类,该实现类继承自AbstractMojo

 注意这里要通过@Mojo注解指定插件goalPrefix,否则插件无法生成成功

6、mvn clean install生成插件

4、测试自定义插件

1、创建maven过程

 注意:一定要指定执行阶段,否则插件无法正常运行

2、执行mvn Mojo:mojo,看到正常调用自定义Mojo

至此,一个简单的Maven Plugin插件就编写完成了。大家可以在熟悉这个操作的基础上编写自己的需求代码。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章