文章目录
- 01 引言
- 02 根节点
- 03 maven插件管理
- 04 profiles(多版本管理)
- 05 assembly打包(归档管理)
- 06 文末
01 引言
博主在上一篇博客《深度剖析Dinky源码》主要分析了dinky
的项目结构,以及源码执行流程。
同时,博主发现该项目的maven
打包也是有值得学习的地方,我们看看其结构:
本文来讲解下Dinky是如何使用maven的特性来打包的。
02 根节点
这里是精简了根节点的pom文件内容之后,添加注释的内容:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Maven项目的POM文件 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Maven项目的模型版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 项目的唯一标识符 -->
<groupId>org.dinky</groupId>
<artifactId>dinky</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 项目的名称 -->
<name>Dinky :</name>
<!-- 包含的子模块列表 -->
<modules>
<module>dinky-admin</module>
<module>dinky-assembly</module>
<!-- 其他依赖,这里不再详述。。。。 -->
</modules>
<!-- 属性列表 -->
<properties>
<!-- 运行时范围为provided(用于生产环境)或compile(用于开发环境) -->
<scope.runtime>provided</scope.runtime>
<snakeyaml.version>1.33</snakeyaml.version>
<!-- 其它属性,这里不再详述。。。 -->
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
<!-- 其它依赖,这里不再详述。。。 -->
</dependencies>
</dependencyManagement>
<!-- 构建配置 -->
<build>
<!-- 插件管理 -->
<pluginManagement>
<plugins>
<!-- 清理插件,用于清理目标目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
</plugin>
<!-- 编译插件,用于编译源代码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<!-- 源码和目标字节码版本 -->
<source>${target.java.version}</source>
<target>${target.java.version}</target>
<testSource>${target.java.version}</testSource>
<testTarget>${target.java.version}</testTarget>
</configuration>
</plugin>
<!-- 其它插件 -->
</plugins>
</pluginManagement>
<!-- 插件列表 -->
<plugins>
<!-- 帮助插件,用于显示Maven帮助信息 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
</plugin>
<!-- 依赖插件,用于管理项目依赖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<!-- 其它插件 -->
</plugins>
</build>
<!-- 项目的URL -->
<url>http://www.dlink.top</url>
<!-- 项目的初始年份 -->
<inceptionYear>2014</inceptionYear>
<!-- 项目的许可证信息 -->
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<!-- 项目的源代码管理信息 -->
<scm>
<connection>git@github.com:DataLinkDC/dinky.git</connection>
<url>https://github.com/DataLinkDC/dinky</url>
</scm>
<!-- 项目的仓库配置 -->
<repositories>
<repository>
<id>apache-snapshots</id>
<url>https://maven.aliyun.com/repository/apache-snapshots</url>
</repository>
</repositories>
<!-- 配置不同的Maven配置文件 -->
<profiles>
<!-- 阿里云仓库配置 -->
<profile>
<id>aliyun</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/central</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/central</url>
</pluginRepository>
</pluginRepositories>
</profile>
<!-- Web配置 -->
<profile>
<id>web</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 开发环境配置 -->
<profile>
<id>dev</id>
<properties>
<!-- 运行时范围为compile(用于开发环境) -->
<scope.runtime>compile</scope.runtime>
</properties>
</profile>
<!-- 生产环境配置 -->
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>!dev</name>
</property>
</activation>
<properties>
<!-- 运行时范围为provided(用于生产环境) -->
<scope.runtime>provided</scope.runtime>
</properties>
</profile>
<!-- Flink 1.14配置 -->
<profile>
<id>flink-1.14</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<dinky.flink.version>1.14</dinky.flink.version>
</properties>
</profile>
<!-- Flink 1.15配置 -->
<profile>
<id>flink-1.15</id>
<properties>
<dinky.flink.version>1.15</dinky.flink.version>
</properties>
</profile>
<!-- 其它配置 -->
</profiles>
</project>
从内容里面,相较于普通的项目,个人认为比较值得去学习的是里面的 插件管理(Plugins
)、打包多版本管理(Profiles
)、以及 assembly
打包管理 ,下面来讲下。
03 maven插件管理
从根目录下的pom文件节点,可以看到在build
节点下,定义了pluginManagement
(插件管理节点)和plugins
(插件列表节点)。
大致有如下内容,它们的作用是:
插件类型 | artifactId | 作用 |
清理插件 | maven-clean-plugin | 清理项目构建产生的文件和目录 |
编译插件 | maven-compiler-plugin | 编译Java源代码 |
单元测试插件 | maven-surefire-plugin | 运行单元测试 |
帮助插件 | maven-help-plugin | 提供Maven帮助文档 |
依赖管理插件 | maven-dependency-plugin | 管理项目的依赖 |
强制执行插件 | maven-enforcer-plugin | 强制执行项目构建规则 |
JAR插件 | maven-jar-plugin | 创建可执行的JAR文件 |
代码格式化插件 | spotless-maven-plugin | 格式化代码和POM文件,以及进行其他代码检查和修复操作 |
构建助手插件 | build-helper-maven-plugin | 帮助处理构建过程中的辅助任务 |
Shade插件 | maven-shade-plugin | 创建可执行的Uber JAR,将所有依赖打包到一个JAR文件中 |
Japicmp插件 | japicmp-maven-plugin | 比较两个Java类或JAR文件之间的差异 |
Javadoc插件 | maven-javadoc-plugin | 生成Java文档 |
值得注意的是,该项目还可以打包web
项目,直接切换到dinky-web/pom.xml
,里面pom
的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.dinky</groupId>
<artifactId>dinky</artifactId>
<!-- 指定父项目的版本 -->
<version>1.0.0-SNAPSHOT</version>
</parent>
<!-- 当前子项目的artifactId -->
<artifactId>dinky-web</artifactId>
<packaging>pom</packaging>
<!-- 项目名称 -->
<name>Dinky : Dinky-Web</name>
<build>
<!-- 构建产物的最终名称,使用当前项目的artifactId和version -->
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<!-- 调用npm命令插件 -->
<plugin>
<!-- 插件的groupId -->
<groupId>com.github.eirslett</groupId>
<!-- 插件的artifactId -->
<artifactId>frontend-maven-plugin</artifactId>
<!-- 插件的版本号 -->
<version>1.12.0</version>
<configuration>
<!-- 指定所需的Node.js版本 -->
<nodeVersion>v14.17.0</nodeVersion>
<!-- 指定所需的npm版本 -->
<npmVersion>7.19.0</npmVersion>
<!-- 国内node下载加速 -->
<!--<nodeDownloadRoot>https://mirrors.huaweicloud.com/nodejs/</nodeDownloadRoot>-->
<!--<npmDownloadRoot>https://repo.huaweicloud.com/npm-software/</npmDownloadRoot>-->
</configuration>
<executions>
<execution>
<!-- 执行命令的唯一标识符 -->
<id>install node and npm</id>
<goals>
<!-- 要执行的目标(goal) -->
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<!-- 执行命令的唯一标识符 -->
<id>npm install</id>
<goals>
<!-- 要执行的目标(goal) -->
<goal>npm</goal>
</goals>
<configuration>
<!-- 国内npm源加速可在后面加入(去掉空格) - -registry https://repo.huaweicloud.com/repository/npm/ -->
<arguments>install --force</arguments> <!-- npm命令及其参数 -->
</configuration>
</execution>
<execution>
<!-- 执行命令的唯一标识符 -->
<id>npm run build</id>
<goals>
<!-- 要执行的目标(goal) -->
<goal>npm</goal>
</goals>
<configuration>
<!-- npm命令及其参数 -->
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
其实原理就是使用了前端的打包插件(frontend-maven-plugin
),执行与npm相关的操作
04 profiles(多版本管理)
Profiles
提供了一种灵活和可配置的方式,能够根据不同的需求和环境来定制和管理项目的构建过程和行为,这使得开发者可以更好地适应不同的开发、测试和部署场景。
从上图可以得知,通过选择右侧的能指定特定的profile,同时也可以使用maven命令来构建(使用-P的形式,逗号分隔多环境),例如:
# 如若修改版本,按以下指定即可。flink可支持多版本(1.11-1.16)
mvn clean install -Dmaven.test.skip=true -P pord,scala-2.11,flink-1.14
这是,dinky官网提示不同profile的作用:
05 assembly打包(归档管理)
在根目录的pom
节点,modules
下,含有dinky-assembly
模块,它允许将多个文件和依赖项聚合成一个可执行的分发包或归档文件,方便部署和发布项目。
进入dinky-assembly目录,看看器其pom文件里面的内容(已含注释):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 定义父项目信息 -->
<parent>
<groupId>org.dinky</groupId>
<artifactId>dinky</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<!-- 项目的唯一标识符 -->
<artifactId>dinky-assembly</artifactId>
<!-- 打包类型为 POM,不生成实际的构建产物 -->
<packaging>pom</packaging>
<!-- 项目名称 -->
<name>Dinky : Assembly</name>
<!-- 构建配置 -->
<build>
<!-- 构建插件 -->
<plugins>
<!-- Maven Assembly 插件 -->
<plugin>
<!-- 插件的groupId -->
<groupId>org.apache.maven.plugins</groupId>
<!-- 插件的artifactId -->
<artifactId>maven-assembly-plugin</artifactId>
<!-- 插件的执行配置 -->
<executions>
<!-- 执行配置 -->
<execution>
<!-- 执行的目标阶段 -->
<phase>package</phase>
<!-- 执行的目标 -->
<goals>
<goal>single</goal>
</goals>
<!-- 插件的配置 -->
<configuration>
<!-- 最终生成的分发包的名称 -->
<finalName>${project.parent.artifactId}-release-${project.version}</finalName>
<!-- 是否追加 Assembly 的标识符到最终生成的分发包名称中 -->
<appendAssemblyId>false</appendAssemblyId>
<!-- 指定 Assembly 描述符的位置 -->
<descriptors>
<descriptor>src/main/assembly/package.xml</descriptor>
</descriptors>
<!-- 最终生成的分发包的输出目录 -->
<outputDirectory>${project.parent.basedir}/build/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
再进入Assembly 描述文件(src/main/assembly/package.xml
),看看里面的内容:
<assembly>
<!-- 分发包的唯一标识符,使用项目的版本号 -->
<id>${project.version}</id>
<!-- 分发包的格式 -->
<formats>
<format>tar.gz</format>
</formats>
<!-- 是否包含基础目录 -->
<includeBaseDirectory>true</includeBaseDirectory>
<!-- 文件集合配置 -->
<fileSets>
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/script/bin</directory>
<!-- 文件输出目录 -->
<outputDirectory>./</outputDirectory>
<!-- 文件行结束符类型 -->
<lineEnding>unix</lineEnding>
<!-- 文件权限模式 -->
<fileMode>0755</fileMode>
<!-- 包含的文件 -->
<includes>
<include>auto.sh</include>
</includes>
</fileSet>
<!-- 定义另一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/dinky-admin/target/classes</directory>
<!-- 文件输出目录 -->
<outputDirectory>config</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>**/*.yml</include>
<include>**/*.yaml</include>
<include>**/log4j2.xml</include>
<include>**/DinkyFlinkDockerfile</include>
</includes>
</fileSet>
<!-- 更多文件集合的定义,下面列举部分示例 -->
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/build/extends/</directory>
<!-- 文件输出目录 -->
<outputDirectory>plugins/flink1.13</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>dinky-catalog-mysql-1.13-${project.version}.jar</include>
<include>dinky-client-1.13-${project.version}.jar</include>
<include>dinky-connector-jdbc-1.13-${project.version}.jar</include>
</includes>
</fileSet>
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/build/extends/</directory>
<!-- 文件输出目录 -->
<outputDirectory>plugins/flink1.14</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>dinky-catalog-mysql-1.14-${project.version}.jar</include>
<include>dinky-client-1.14-${project.version}.jar</include>
<include>dinky-connector-jdbc-1.14-${project.version}.jar</include>
</includes>
</fileSet>
<!-- 更多文件集合的定义,下面列举部分示例 -->
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/build/extends/</directory>
<!-- 文件输出目录 -->
<outputDirectory>plugins</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>dinky-client-base-${project.version}.jar</include>
</includes>
</fileSet>
<!-- 更多文件集合的定义,下面列举部分示例 -->
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/dinky-metadata/dinky-metadata-clickhouse/target</directory>
<!-- 文件输出目录 -->
<outputDirectory>lib</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>dinky-metadata-clickhouse-${project.version}.jar</include>
</includes>
</fileSet>
<!-- 更多文件集合的定义,下面列举部分示例 -->
<!-- 定义一个文件集合 -->
<fileSet>
<!-- 文件所在目录 -->
<directory>${project.parent.basedir}/docker/app</directory>
<!-- 文件输出目录 -->
<outputDirectory>jar</outputDirectory>
<!-- 包含的文件 -->
<includes>
<include>Dockerfile</include>
</includes>
</fileSet>
<!-- 更多文件集合的定义 -->
</fileSets>
</assembly>
以上是 <assembly>
元素的配置,它定义了如何将不同的文件集合打包到分发包中。每个 <fileSet>
元素指定了一个文件集合,包括要打包的文件所在的目录、输出目录和包含的文件。
通过配置多个 <fileSet>
元素,可以将不同的文件组织结构打包到分发包中。
06 文末
如果想更进一步去学习maven的高级特性,可以直接搜索maven的官网,里面有更丰富的教程:https://maven.apache.org/
希望能帮助到大家,谢谢大家的阅读,本文完!