Maven 基础教程(三):build、profile

《Maven 基础教程》系列,包含以下 5 篇文章:

Maven 基础教程(一):基础介绍、开发环境配置
Maven 基础教程(二):Maven 的使用
Maven 基础教程(三):build、profile
Maven 基础教程(四):搭建 Maven 私服 Nexus
Maven 基础教程(五): jar 包冲突问题

4.build 标签

在实际使用 Maven 的过程中,我们会发现 build 标签有时候有,有时候没,这是怎么回事呢?其实通过有效 POM 我们能够看到,build 标签的相关配置其实一直都在,只是在我们需要定制构建过程的时候才会通过配置 build 标签覆盖默认值或补充配置。这一点我们可以通过打印有效 POM 来看到。

打印有效 pom

mvn help:effective-pom

当默认配置无法满足需求的定制构建的时候,就需要使用 build 标签。

4.1 build 标签的组成

build 标签的子标签大致包含三个主体部分:

1️⃣ 定义约定的目录结构
2️⃣ 备用插件管理
3️⃣ 生命周期插件

4.1.1 定义约定的目录结构

<sourceDirectory>D:\product\maven-demo-parent\demo-module\src\main\java</sourceDirectory>
<scriptSourceDirectory>D:\product\maven-demo-parent\demo-module\src\main\scripts</scriptSourceDirectory>
<testSourceDirectory>D:\product\maven-demo-parent\demo-module\src\test\java</testSourceDirectory>
<outputDirectory>D:\product\maven-demo-parent\demo-module\target\classes</outputDirectory>
<testOutputDirectory>D:\product\maven-demo-parent\demo-module\target\test-classes</testOutputDirectory>
<resources>
    <resource>
        <directory>D:\product\maven-demo-parent\demo-module\src\main\resources</directory>
    </resource>
</resources>
<testResources>
    <testResource>
        <directory>D:\product\maven-demo-parent\demo-module\src\test\resources</directory>
    </testResource>
</testResources>
<directory>D:\product\maven-demo-parent\demo-module\target</directory>
<finalName>demo-module-1.0-SNAPSHOT</finalName>

各个目录的作用如下:

目录名作用
sourceDirectory主体源程序存放目录
scriptSourceDirectory脚本源程序存放目录
testSourceDirectory测试源程序存放目录
outputDirectory主体源程序编译结果输出目录
testOutputDirectory测试源程序编译结果输出目录
resources主体资源文件存放目录
testResources测试资源文件存放目录
directory构建结果输出目录

4.1.2 备用插件管理

pluginManagement 标签存放着几个极少用到的插件:

  • maven-antrun-plugin
  • maven-assembly-plugin
  • maven-dependency-plugin
  • maven-release-plugin

通过 pluginManagement 标签管理起来的插件就像 dependencyManagement 一样,子工程使用时可以省略版本号,起到在父工程中统一管理版本的效果。

4.1.3 生命周期插件

plugins 标签存放的是默认生命周期中实际会用到的插件,这些插件想必大家都不陌生,所以抛开插件本身不谈,plugin 标签的结构如下:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <executions>
        <execution>
            <id>default-compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
        <execution>
            <id>default-testCompile</id>
            <phase>test-compile</phase>
            <goals>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

坐标部分

  • artifactId 和 version 标签定义了插件的坐标,作为 Maven 的自带插件这里省略了 groupId。

执行部分

  • executions 标签内可以配置多个 execution 标签,execution 标签内:
    • id:指定唯一标识
    • phase:关联的生命周期阶段
    • goals / goal:关联指定生命周期的目标。goals 标签中可以配置多个 goal 标签,表示一个生命周期环节可以对应当前插件的多个目标。

4.2 典型应用:指定 JDK 版本

前面我们在 settings.xml 中配置了 JDK 版本**,那么将来把 Maven 工程部署都服务器上,脱离了 settings.xml 配置,如何保证程序正常运行呢?思路就是我们直接把 JDK 版本信息告诉负责编译操作的 maven-compiler-plugin 插件,让它在构建过程中,按照我们指定的信息工作**。如下:

<!-- build 标签:意思是告诉 Maven,你的构建行为,我要开始定制了!-->
<build>
    <!-- plugins 标签:Maven 你给我听好了,你给我构建的时候要用到这些插件!-->
    <plugins>
        <!-- plugin 标签:这是我要指定的一个具体的插件 -->
        <plugin>
            <!-- 插件的坐标。此处引用的 maven-compiler-plugin 插件不是第三方的,是一个 Maven 自带的插件。-->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>

            <!-- configuration 标签:配置 maven-compiler-plugin 插件 -->
            <configuration>
                <!-- 具体配置信息会因为插件不同、需求不同而有所差异 -->
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

  • settings.xml 中配置:仅在本地生效,如果脱离当前 settings.xml 能够覆盖的范围,则无法生效。
  • 在当前 Maven 工程 pom.xml 中配置:无论在哪个环境执行编译等构建操作都有效。

4.3 典型应用:SpringBoot 定制化打包

很显然 spring-boot-maven-plugin 并不是 Maven 自带的插件,而是 SpringBoot 提供的,用来改变 Maven 默认的构建行为。具体来说是改变打包的行为。默认情况下 Maven 调用 maven-jar-plugin 插件的 jar 目标,生成普通的 jar 包。

普通 jar 包没法使用 java -jar xxx.jar 这样的命令来启动、运行,但是 SpringBoot 的设计理念就是每一个 微服务 导出为一个 jar 包,这个 jar 包可以使用 java -jar xxx.jar 这样的命令直接启动运行。

这样一来,打包的方式肯定要进行调整。所以 SpringBoot 提供了 spring-boot-maven-plugin 这个插件来定制打包行为。

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>2.5.5</version>
    </plugin>
  </plugins>
</build>

5. 依赖配置补充

管理依赖最基本的办法是继承父工程,但是和 Java 类一样,Maven 也是单继承的。如果不同体系的依赖信息封装在不同 POM 中了,没办法继承多个父工程怎么办?这时就可以使用 import 依赖范围。

详见Maven的依赖传递

5.1 import

典型案例当然是在项目中引入 SpringBoot、SpringCloud 依赖:

<dependencyManagement>
    <dependencies>
        <!-- SpringCloud 微服务 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- SpringCloud Alibaba 微服务 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

  • import 依赖范围使用要求:

    • 打包类型必须是 pom
    • 必须放在 dependencyManagement 中

5.2 system

以 Windows 系统环境下开发为例,假设现在 D:\product\maven-demo-parent\demo-module\target\demo-module-1.0-SNAPSHOT.jar 想要引入到我们的项目中,此时我们就可以将依赖配置为 system 范围:

<dependency>
    <groupId>net.javatv.maven</groupId>
    <artifactId>demo-module</artifactId>
    <version>1.0-SNAPSHOT</version>
    <systemPath>D:\product\maven-demo-parent\demo-module\target\demo-module-1.0-SNAPSHOT.jar</systemPath>
    <scope>system</scope>
</dependency>

<dependency>
            <groupId>aspose-cad</groupId>
            <artifactId>aspose-cad</artifactId>
            <version>20.10</version>
            <scope>system</scope>
            <systemPath>${pom.basedir}/src/main/resources/lib/aspose-cad-20.10.jar</systemPath>
        </dependency>

在Maven 打包需要把外部依赖包打进jar包时候需要 再 spring-boot-maven-plugin 插件中 true 标签设置为ture 打进依赖包

 <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>avicit.AvicitVpdmApplication</mainClass>
                    <!--设置为true,以便把本地的system的jar也包括进来-->
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

 </build>

5.3 runtime

专门用于编译时不需要,但是运行时需要的 jar 包。比如:编译时我们根据接口调用方法,但是实际运行时需要的是接口的实现类。典型案例是:

<!--热部署 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

6.profile

6.1 profile 概述
这里我们可以对接 profile 这个单词中 侧面 这个含义:项目的每一个运行环境,相当于是项目整体的一个侧面。

在这里插入图片描述
通常情况下,我们项目至少有三种运行环境:

  • 开发环境:供不同开发工程师开发的各个模块之间互相调用、访问;内部使用。

  • 测试环境:供测试工程师对项目的各个模块进行功能测试;内部使用。

  • 生产环境:供最终用户访问,所以这是正式的运行环境,对外提供服务。
    在这里插入图片描述
    我们这里的 环境 仍然只是一个笼统的说法,实际工作中一整套运行环境会包含很多种不同服务器:

  • MySQL

  • Redis

  • ElasticSearch

  • RabbitMQ

  • FastDFS

  • Nginx

  • Tomcat
    ……
    就拿其中的 MySQL 来说,不同环境下的访问参数肯定完全不同,可是代码只有一套。如果在 jdbc.properties 里面来回改,那就太麻烦了,而且很容易遗漏或写错,增加调试的难度和工作量。所以最好的办法就是把适用于各种不同环境的配置信息分别准备好,部署哪个环境就激活哪个配置。

在 Maven 中,使用 profile 机制来管理不同环境下的配置信息。但是解决同类问题的类似机制在其他框架中也有,而且从模块划分的角度来说,持久化层的信息放在构建工具中配置也违反了 高内聚,低耦合 的原则。

实际上,即使我们在 pom.xml 中不配置 profile 标签,也已经用到 profile了。为什么呢?因为根标签 project 下所有标签相当于都是在设定默认的 profile。这样一来我们也就很容易理解下面这句话:project 标签下除了 modelVersion 和坐标标签之外,其它标签都可以配置到 profile 中

6.2 profile 配置

6.2.1 外部视角:配置文件

从外部视角来看,profile 可以在下面两种配置文件中配置:

  • settings.xml:全局生效。其中我们最熟悉的就是配置 JDK 1.8。
  • pom.xml:当前 POM 生效。

6.2.2 内部实现:具体标签

从内部视角来看,配置 profile 有如下语法要求:

1️⃣ profiles / profile 标签

  • 由于 profile 天然代表众多可选配置中的一个,所以由复数形式的 profiles 标签统一管理。
  • 由于 profile 标签覆盖了 pom.xml 中的默认配置,所以 profiles 标签通常是 pom.xml 中的最后一个标签。
    2️⃣ id 标签

每个 profile 都必须有一个 id 标签,指定该 profile 的唯一标识。这个 id 标签的值会在命令行调用 profile 时被用到。这个命令格式是:

-D<profile id>

其它允许出现的标签

一个 profile 可以覆盖项目的 最终名称、项目依赖、插件配置 等各个方面以影响构建行为。

  • build
  • defaultGoal
  • finalName
  • resources
  • testResources
  • plugins
  • reporting
  • modules
  • dependencies
  • dependencyManagement
  • repositories
  • pluginRepositories
  • properties

6.3 激活 profile

1️⃣ 默认配置默认被激活

前面提到了,POM 中没有在 profile 标签里的就是默认的 profile,当然默认被激活。

2️⃣ 基于环境信息激活

环境信息包含:JDK 版本、操作系统参数、文件、属性 等各个方面。一个 profile 一旦被激活,那么它定义的所有配置都会覆盖原来 POM 中对应层次的元素。可参考下面的标签结构:

<profile>
  <id>dev</id>
    <activation>
        <!-- 配置是否默认激活 -->
      <activeByDefault>false</activeByDefault>
        <jdk>1.5</jdk>
        <os>
          <name>Windows XP</name>
            <family>Windows</family>
            <arch>x86</arch>
            <version>5.1.2600</version>
        </os>
        <property>
          <name>mavenVersion</name>
            <value>2.0.5</value>
        </property>
        <file>
          <exists>file2.properties</exists>
            <missing>file1.properties</missing>
        </file>
    </activation>
</profile>

这里有个问题是:多个激活条件之间是什么关系呢

  • Maven 3.2.2 之前:遇到第一个满足的条件即可激活,或的关系。
  • Maven 3.2.2 开始:各条件均需满足,且的关系
    下面我们来看一个具体例子。假设有如下 profile 配置,在 JDK 版本为 1.6 时被激活:
<profiles>
  <profile>
      <id>JDK1.6</id>
        <activation>
            <!-- 指定激活条件为:JDK 1.6 -->
          <jdk>1.6</jdk>
        </activation>
        ……
    </profile>
</profiles>

这里需要指出的是:Maven 会自动检测当前环境安装的 JDK 版本,只要 JDK 版本是以 1.6 开头都算符合条件。下面几个例子都符合:

  • 1.6.0_03
  • 1.6.0_02
  • ……

6.4 Maven profile 多环境管理

在开发过程中,我们的软件会面对不同的运行环境,比如开发环境、测试环境、生产环境,而我们的软件在不同的环境中,有的配置可能会不一样,比如数据源配置、日志文件配置、以及一些软件运行过程中的基本配置,那每次我们将软件部署到不同的环境时,都需要修改相应的配置文件,这样来回修改,很容易出错,而且浪费劳动力。

因此我们可以利用 Maven 的 profile 来进行定义多个 profile,然后每个 profile 对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。

<build>
    <!-- profile对资源的操作 -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <!-- 先排除所有环境相关的配置文件 -->
            <excludes>
                <exclude>application*.yml</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <!-- 是否替换 @xx@ 表示的maven properties属性值 -->
            <!--通过开启 filtering,maven 会将文件中的 @xx@ 替换 profile 中定义的 xx 变量/属性-->
            <filtering>true</filtering>
            <includes>
                <include>application.yml</include>
                <include>application-${profileActive}.yml</include>
            </includes>
        </resource>
    </resources>
</build>

<!--多环境文件配置-->
<profiles>
    <!--开发环境-->
    <profile>
        <id>dev</id>
        <activation>
            <!--默认激活-->
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <profileActive>dev</profileActive>
        </properties>
    </profile>
    <!--测试环境-->
    <profile>
        <id>test</id>
        <properties>
            <profileActive>test</profileActive>
        </properties>
    </profile>
    <!--正式环境-->
    <profile>
        <id>prod</id>
        <properties>
            <profileActive>prod</profileActive>
        </properties>
    </profile>
</profiles>

在 idea 中可以看到,因此,当你需要打包哪一个环境的就勾选即可:

在这里插入图片描述
同时,SpringBoot 天然支持多环境配置,一般来说,application.yml 存放公共的配置,application-dev.yml、application-test.yml、application.prod.yml 分别存放三个环境的配置。如下:
在这里插入图片描述
application.yml 中配置 spring.profiles.active=prod(或者 dev、test)指定使用的配置文件,如下:

在这里插入图片描述
注:profileActive,就是上面我们自定义的标签。

然后当我们勾选哪一个环境,打包的配置文件就是那一个环境:
在这里插入图片描述
同时我们再在 resource 标签下看到 includes 和 excludes 标签。它们的作用是:

  • includes:指定执行 resource 阶段时要包含到目标位置的资源。
  • excludes:指定执行 resource 阶段时要排除的资源。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
build-helper-maven-plugin:jar:1.8是一个用于构建Java项目的Maven插件。该插件提供了一些辅助功能,以帮助简化和优化项目构建过程。 首先,build-helper-maven-plugin:jar:1.8可以帮助我们在构建过程中处理一些非常规的任务。例如,它可以通过添加额外的源代码目录来扩展项目的结构,以便在构建过程中包含其他源代码。这对于多模块项目或需要集成外部代码库的项目非常有用。 此外,该插件还提供了一些用于处理资源文件的功能。我们可以使用该插件来复制或移动资源文件到特定的目录,以便在构建过程中正确地包含这些文件。这对于需要在构建期间处理和转换资源文件的项目非常有用,例如压缩JavaScript或CSS文件。 另一个重要的功能是build-helper-maven-plugin:jar:1.8可以帮助我们在构建过程中处理依赖关系。它可以自动将特定的依赖项添加到项目配置中,以便在编译和运行时正确地解决这些依赖项。这对于需要从其他模块或项目引入代码或库的项目非常有用。 除了以上提到的功能,build-helper-maven-plugin:jar:1.8还提供了其他一些辅助功能,如将构建生成的文件添加到构建输出中,生成版本号等。 综上所述,build-helper-maven-plugin:jar:1.8是一个功能强大的Maven插件,可以帮助我们更轻松地构建和管理Java项目。通过提供一些辅助功能,它提高了项目的灵活性和可维护性,使我们能够更加高效地进行构建过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值