Maven入门教程(二)

Maven入门教程(二)

Maven 多模块构建

在之前的章节中,我们已经学习了关于 Maven 的大部分知识。从本节开始,我们会通过开发一个小型项目来更好的理解之前的概念。在这一节中,我们首先要做的就是用 Maven 来构建一个包含多个模块的项目。

1. Project 和 Module

提到多模块项目构建,我们首先要弄明白 project 和 module 这两个概念。

a. 相同点:

  • project 和 module 都是 Maven 工程,有属于自己的 pom.xml。

b. 不同点:

  • module 工程必须要有父项目,一般情况下,project 工程在多模块项目中都是作为父项目存在的;
  • project 工程可以放到类似 tomcat 的容器中运行,而 module 工程则不能;

简单总结一下,project 工程包含的范围更广,单模块项目中作为项目整体,多模块项目中作为父模块存在。module 工程在多模块项目中作为子工程存在。

2. 开始创建项目

2.1 创建 project 工程

这里,我们结合市面上比较常用的开发工具 idea 来进行演示,当然,其他的开发工具也能够得到相同的效果。

刚刚,我们也了解到多模块项目必须要有 project 工程作为父项目存在,那么首先,我们就需要创建一个 project 工程。

Maven入门教程(二)


打开 idea,选择 File -> New -> Project,在弹出的窗口左侧选择 Maven 并点击 Next 按钮。

Maven入门教程(二)

在这里,需要填写 project 的信息,包括 groupId,artifactId,version 信息,并点击 Next 按钮。

Maven入门教程(二)

最后一步,只需要填写项目名称,然后点击Finish按钮即可。

Maven入门教程(二)

由于是父项目,所以并不需要代码,因此可以将 src 目录直接删掉。

Maven入门教程(二)

至此,project 项目创建完成。

2.2 创建 module 工程

在创建好父工程之后,我们开始创建 module 工程。在父工程上点击右键,选择New -> Module

Maven入门教程(二)


我们会发现跟刚刚创建 project 工程的步骤是一样的,只不过其中有些已经不需要我们来填写了,例如 groupId,version 等,这里是因为存在父工程,而子工程的这些元素节点都是继承父工程的。所以我们只需要填写子工程的 artifactId 即可。

这里我们分别创建 mall-account 工程,mall-commodity 工程,mall-order 工程,mall-delivery 工程,分别对应商城系统的用户模块,商品模块,订单模块以及物流模块。

另外我们在单独创建一个 mall-web 工程,主要的功能是作为各个模块的整合并与前端页面进行对接。

在创建 mall-web 工程的时候,需要注意的是,我们要选择一个maven-archetype-webapp的模块。然后点击 Next 按钮,进入下一步。

Maven入门教程(二)

后续操作和其他模块没有太大区别,按照实际情况选择和填写即可。

现在,整个项目已经初具雏形了,我们来看一下现在项目的结构。

Maven入门教程(二)

2.3 添加依赖

注意:mall 项目为一个实例项目,中间可能会存在某些不太合理的地方,我们这里更多的关注项目构建过程。

  1. mall-account 项目为用户项目,需要被 mall-order 项目、mall-delivery 项目和 mall-web 项目依赖;
  2. mall-order 项目为订单项目,需要被 mall-delivery 项目和 mall-web 项目依赖;
  3. mall-commodity 项目为商品项目,需要被 mall-web 模块依赖;
  4. mall-delivery 项目为物流项目,需要被 mall-web 项目依赖。

我们首先在父工程 mall-aggregate 的 pom.xml 文件中,添加 dependencyManagement 节点元素。

<properties>    <junit.version>4.11</junit.version></properties><dependencyManagement>    <dependencies>        <dependency>            <groupId>com.mic.tech</groupId>            <artifactId>mall-account</artifactId>            <version>${project.version}</version>        </dependency>        <dependency>            <groupId>com.mic.tech</groupId>            <artifactId>mall-commodity</artifactId>            <version>${project.version}</version>        </dependency>        <dependency>            <groupId>com.mic.tech</groupId>            <artifactId>mall-order</artifactId>            <version>${project.version}</version>        </dependency>        <dependency>            <groupId>com.mic.tech</groupId>            <artifactId>mall-delivery</artifactId>            <version>${project.version}</version>        </dependency>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>${junit.version}</version>            <scope>test</scope>        </dependency>    </dependencies></dependencyManagement>

然后,依次在各个子工程中,根据子项目之间的依赖关系,添加对应的依赖。在添加完依赖之后,我们可以使用之前安装过的 Maven Helper 插件来生成整个工程的依赖关系图。

Maven入门教程(二)

生成之后的依赖关系图如下:

Maven入门教程(二)


从这个图中,我们可以清楚看到目前 mall 工程各个模块直接的依赖关系。在实际的开发过程中,可以根据生成的依赖关系图来判断是否存在某些没必要引入的依赖,进行依赖优化。

2.4 运行这个项目

在项目创建好之后,我们就来运行这个项目。在 idea 中点击Add Configuration按钮。

Maven入门教程(二)

在弹出的界面点击小+号,然后选择 Tomcat Server -> Local

Maven入门教程(二)


在 Tomcat Server 界面的 Deployment 页签,点击小+号,选择Artifact… ,并在弹出的窗口中,选择mallweb:war exploded,并在Application context中输入/index ,最后点击OK按钮。

Maven入门教程(二)

点击Add Configuration 旁边的三角形按钮,启动项目,项目启动后控制台会输出如下日志产生。

Maven入门教程(二)


项目启动成功后,我们在浏览器中输入地址http://localhost:8080/index/,可以看到项目的欢迎页面。

Maven入门教程(二)

至此,我们的项目已经创建并启动完成。

3. 构建这个项目

有了之前章节的铺垫,项目构建就变得非常容易了。

我们将目录切换到 mall-aggregate 目录下,执行 mvn clean install 命令,就可以得到如下执行结果。

[INFO] Scanning for projects...[WARNING][WARNING] Some problems were encountered while building the effective model for com.mic.tech:mall-web:war:1.0.0-SNAPSHOT[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: junit:junit:jar -> duplicate declaration of version (?) @ line 46, column 17[WARNING][WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.[WARNING][WARNING] For this reason, future Maven versions might no longer support building such malformed projects.[WARNING][INFO] ------------------------------------------------------------------------[INFO] Reactor Build Order:[INFO][INFO] mall-aggregate                                                     [pom][INFO] mall-account                                                       [jar][INFO] mall-commodity                                                     [jar][INFO] mall-order                                                         [jar][INFO] mall-delivery                                                      [jar][INFO] mall-web Maven Webapp                                              [war][INFO][INFO] --------------------< com.mic.tech:mall-aggregate >---------------------[INFO] Building mall-aggregate 1.0.0-SNAPSHOT                             [1/6][INFO] --------------------------------[ pom ]---------------------------------[INFO] ...[INFO] ---------------------< com.mic.tech:mall-account >----------------------[INFO] Building mall-account 1.0.0-SNAPSHOT                               [2/6][INFO] --------------------------------[ jar ]---------------------------------[INFO] ...[INFO] --------------------< com.mic.tech:mall-commodity >---------------------[INFO] Building mall-commodity 1.0.0-SNAPSHOT                             [3/6][INFO] --------------------------------[ jar ]---------------------------------[INFO] ...[INFO] ----------------------< com.mic.tech:mall-order >-----------------------[INFO] Building mall-order 1.0.0-SNAPSHOT                                 [4/6][INFO] --------------------------------[ jar ]---------------------------------[INFO] ...[INFO] ---------------------< com.mic.tech:mall-delivery >---------------------[INFO] Building mall-delivery 1.0.0-SNAPSHOT                              [5/6][INFO] --------------------------------[ jar ]---------------------------------[INFO] ...[INFO] -----------------------< com.mic.tech:mall-web >------------------------[INFO] Building mall-web Maven Webapp 1.0.0-SNAPSHOT                      [6/6][INFO] --------------------------------[ war ]---------------------------------[INFO] ...[INFO] Building war: D:\code\mall-aggregate\mall-web\target\mall-web.war[INFO] ------------------------------------------------------------------------[INFO] Reactor Summary for mall-aggregate 1.0.0-SNAPSHOT:[INFO][INFO] mall-aggregate ..................................... SUCCESS [  0.897 s][INFO] mall-account ....................................... SUCCESS [  2.173 s][INFO] mall-commodity ..................................... SUCCESS [  0.191 s][INFO] mall-order ......................................... SUCCESS [  0.192 s][INFO] mall-delivery ...................................... SUCCESS [  0.148 s][INFO] mall-web Maven Webapp .............................. SUCCESS [  3.331 s][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  7.154 s[INFO] Finished at: 2020-05-09T22:55:42+08:00[INFO] ------------------------------------------------------------------------

4. 小结

在本章节中,我们完成了 mall 工程的搭建,运行,构建的整个过程,本节中并没有太多新的内容,都是基于之前章节的内容,进行整合,后续的章节也会使用这个示例项目来进行讲解。

Maven 单元测试

在我们平时开发的过程中,测试环节是永远不能避免的。那我们如何能够快速的进行单元测试呢,如何更方便的看到测试结果呢?在这个过程中,Maven 也能够为我们提供帮助,那我们来看看 Maven 如何在测试环节来辅助我们的。

1. 使用 Maven 进行单元测试

1.1 添加测试代码

这里面我们在 mall-order 模块中增加生成订单的方法,这个方法调用后会生成一个 OrderEntity 对象,里面包括订单编号(orderNuM)和订单所有者(orderOwner)两个字段。(这里我们仅仅是用来模拟单元测试,对业务的具体逻辑不做过多纠结)

首先,我们在 mall-order 模块的 pom.xml 文件中添加需要的依赖。

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>

添加依赖后,我们在项目中创建 service 目录和 entity 目录,分别用于存放项目的服务层代码和实体类。

Maven入门教程(二)

在项目中添加对应的 service 和 entity

并且在对应的测试目录中,增加该服务层代码的测试类 OrderServiceTest

Maven入门教程(二)

完成后,我们可以执行该测试用例,来调试 OrderService 中的 generateOrder 方法。

Maven入门教程(二)

从调试结果来看,我们的方法被成功调用,并且没有异常。

1.2 借助 Maven 进行单元测试

后来,随着我们项目的不断进行,我们开发的功能也随之不断增多,相应的,不同功能的测试用例也在不断的增多。这个时候,如果单纯的靠开发人员手工去点击每一个测试用例,这显然是不合理的。

那么我们就可以借助 Maven 来帮助我们做这件事情,来进行自动化的单元测试。

例如在 mall-order 模块下, 我们想要执行所有的单元测试用例,那么我们只需要进入到该模块的根目录下,执行 mvn test 命令即可。

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.mic.tech:mall-order >-----------------------
[INFO] Building mall-order 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ...
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mall-order ---
[INFO] Surefire report directory: D:\code\mall-aggregate\mall-order\target\surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.mic.tech.OrderServiceTest
...
Results :

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.333 s
[INFO] Finished at: 2020-05-20T23:37:40+08:00
[INFO] ------------------------------------------------------------------------


从执行结果,我们可以看出,一共执行了三个测试用例,没有失败,也没有报错的情况出现。

2. 跳过测试

2.1 指定测试用例进行测试

其实每一项新的操作一般都会伴随一些问题产生。例如,我们在实际的开发过程中,有些时候只是改动了一处代码,但是如果直接执行 mvn test 命令的话,会将整个项目的测试用例全部都执行一遍,这对于我们来说,是有些得不偿失的,没必要因为一处改动,而去测试其他几十个或者几百个测试用例。

那我们应该怎么办呢?这里我们为了演示,写了两个测试类,OrderServiceTest 和OrderService2Test,其中第一个类中,有两个测试用例,第二个类中,只有一个测试用例。

这时候,我们修改了第二个类中测试用例对应的方法,需要重新进行单元测试。我们可以直接执行命令:mvn test -Dtest=OrderService2Test

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.mic.tech:mall-order >-----------------------
[INFO] Building mall-order 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ...
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mall-order ---
[INFO] Surefire report directory: D:\code\mall-aggregate\mall-order\target\surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.mic.tech.OrderService2Test
...
Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.261 s
[INFO] Finished at: 2020-05-21T22:17:47+08:00
[INFO] ------------------------------------------------------------------------


从结构来看,我们这里只执行了第二个测试类中的测试用例。

2.2 跳过测试

换到另外一个场景,构建项目的时候。在平时的开发过程中,我们经常会使用mvn package构建项目,但是如果这个项目比较庞大,测试用例会非常多,那么执行测试用例的过程就会非常耗时。那怎么办呢,test 阶段在 package 阶段之前,如果直接执行 package 阶段,test 阶段势必会被执行到。

这个时候我们可以跳过测试来构建项目。(当然,这样的做法是不被建议的)

在执行构建命令的时候,添加参数来指定跳过测试即可,mvn package -DskipTests 或者 mvn package -Dmaven.test.skip=true

这两个命令虽然都能够在构建项目的时候跳过测试,但还是有些区别的。

  • -DskipTests: 会编译测试类;
  • -Dmaven.test.skip=true: 不会编译测试类。

3. 测试报告

Maven 的默认配置中,会在 target\surefire-reports 目录下生成测试报告。

我们执行 mvn clean test,就可以观察到该目录生成。

Maven入门教程(二)

我们可以在 txt 格式的文档中看到生成的测试报告。这里的测试报告基本上和控制台输出的内容是类似的。

大家可能也注意到了,我们在执行测试用例的时候,同时生成了两种类型的文件,一种是 txt 格式,另一个则是 XML 格式。

  • txt 格式: 为了让执行测试用例的开发者更加直观的看到测试用例的运行结果;
  • XML格式: 更多的是为了支持其他工具的解析。

4. maven-surefire-plugin

说了这么多,其实 Maven 之所以可以帮助我们自动执行测试用例,还是依靠 maven-surefire-plugin 插件来实现的。在学过 Maven 的生命周期之后,我们知道一个插件的功能都是通过目标来实现的,而不同的目标则会和生命周期中的不同阶段进行绑定。这里,生命周期中的 test 阶段就是和 maven-surefire-plugin 插件的 test 目标进行绑定的。

对于 Maven 来说,我们可以不指定或者显示的声明该插件。

在显示声明的时候,我可以通过添加 configuration 的方式来实现刚刚执行命令的效果。

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>

例如我们在 configuration 中添加 skipTests 节点,则可以默认跳过测试。当我们再次执行mvn package命令构建项目的时候,test 阶段是不会被执行的。

当然,我们也可以在 configuration 中添加 include 节点和 exclude 节点,来控制执行的测试类。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<includes>
<include>**/OrderServiceTest.java</include>
</includes>
<excludes>
<exclude>**/OrderService2Test.java</exclude>
</excludes>
</configuration>
</plugin>

此时,我们再次执行mvn test的时候会发现只有OrderServiceTest.java类中的测试用例被执行了。

5. 小结

在本节的学习中,我们简单介绍了如何编写测试用例,Maven 如何自动的执行测试用例,以及在执行测试用例的过程中的一些技巧,比如跳过测试。最后我们还介绍了 maven-surefire-plugin 的简单使用。通过本节的学习,我们可以使用 Maven 轻松的进行自动化测试。

Maven 使用 Profile 构建

上一节,我们讲到了如何使用 Maven 自动化的进行单元测试,那测试通过之后,我们就要进行构建,并且将构建好的程序包,放到对应的服务器上去运行。这个时候,问题就出现了,对于不同环境,我们需要不同的配置文件,那我们构建的之前,就需要将配置文件改为对应环境的配置文件,之后才能进行构建。总而言之,很麻烦,而且,万一忘记改配置,那么构建出来的包就是错的。

Profile 则让不同环境之间可移植性的构建成为可能。它使我们在构建项目的时候,可以很轻松的在不同环境中进行构建,也可以称之为“开箱即用”。

1. 可移植性

首先,我们来介绍一下可移植性。所谓的可移植性,指的是,在构建的过程中,改动配置文件的次数和范围越小,则可移植性越强,反之,则可移植性越弱。根据可移植性的不同程度,我们可以将其划分为如下几类:

  • 不可移植: 指的是,项目只能在某个特定环境或者条件下才能构建。这种时候,构建是不可移植的,当然,我们在开发的过程中,肯定是不想看到这种情况的发生。
  • 环境可移植: 指的是,对于不同环境添加不同的配置,一次构建都能够完成,那么这个构建就具备环境可移植了。即:无需对不同环境做过多改动,即可完成相应构建。
  • 全局可移植: 指的是,无论在何种环境下,开发者都不需要做任何配置,即可完成对项目的构建工作。这个特性对于优秀的开源软件来说,尤其重要。因为这种类型的软件,往往会由来自各地的开发者来共同开发。

在大多数情况下,我们平时开发的项目只需要做到环境可移植就可以了。因为通常的公司往往会有三套环境,开发环境,测试环境,生产环境,针对不同的开发阶段,往往需要将项目构建到不同的环境中去,但是由于这些项目通常部署在公司的内网环境中,所以,我们并不需要考虑做到全局可移植性。

2. Maven Profile

在了解了什么是可移植性之后,那我们来看看 Maven 是如何实现可移植性的。这里就需要介绍 Maven 的一组配置 Profile 。通过使用 Profile 我们就可以实现针对不同环境自定义进行构建。通常情况下,Profile 被定义在 pom.xml 文件中,但是定义的方式也可以有很多种。

<profiles>
<profile>
<id>dev</id>
<properties>
<database.driver>com.mysql.cj.jdbc.Driver</database.driver>
<database.url>jdbc:mysql://localhost:3306/dev</database.url>
<database.username>Mic</database.username>
<database.password>Abc123</database.password>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<database.driver>com.mysql.cj.jdbc.Driver</database.driver>
<database.url>jdbc:mysql://localhost:3306/test</database.url>
<database.username>Mic</database.username>
<database.password>Abc123</database.password>
</properties>
</profile>
</profiles>

这里我们以数据库连接串为例,可以将不同环境中的数据库连接串配置到对应的 profile 节点中,并为每个 profile 节点定义单独的 id 。配置好之后,我们我们在进行构建项目的时候,可以在执行命令的时候,加上参数 -Pdev 来指定对应的配置 :mvn clean package -Pdev

但是问题来了,通常情况下,我们不会把配置信息放到 pom.xml 文件中,这样对于我们管理配置,并不方便。那我们如何在构建的时候,指定使用对应的配置文件来进行构建呢?我们可以对 pom.xml 文件进行简单的修改。

<build>    <finalName>mall-order</finalName>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>            <configuration>            	<executable>true</executable>            </configuration>        </plugin>    </plugins>    <resources>        <resource>        	<directory>src/main/resources/</directory>        	<!-- 打包时,将对应配置文件先排除 -->            <excludes>            	<exclude>**/*.yml</exclude>            </excludes>            <includes>            <!--如果有其他定义通用文件,需要包含进来-->            </includes>        </resource>        <resource>            <!-- 通过自定义的节点来激活指定的配置文件 -->            <directory>src/main/resources/${profile.active}</directory>        </resource>    </resources></build><profiles>    <profile>        <id>dev</id>        <properties>            <!-- 自定义节点profile.active-->            <profile.active>dev</profile.active>        </properties>        <!--activation用来指定激活方式,可以根据jdk环境,环境变量,文件的存在或缺失-->        <activation>            <!-- 表示默认激活-->            <activeByDefault>true</activeByDefault>        </activation>    </profile>    <profile>        <id>test</id>        <properties>        	<profile.active>test</profile.active>        </properties>    </profile>

首先,我们定义 resource 节点用于指定配置文件的目录,并将最后一级目录定义成可配置的。然后,跟刚刚类似,我们开始定义 profiles 节点,只不过这次,我们只是在 properties 节点中自定义了一个节点,与 resource 中的自定义路径相呼应。相应的,我们需要在 resources目录下,创建两个目录,分别为 dev 和 prod 目录,用于存放不同的配置文件。

Maven入门教程(二)

都配置好之后,我们再使用命令 mvn clean package -Pdev 来构建项目。构建完成后,我们查看目录target\classes 会发现,application-dev.yml 配置文件被编译进来,而另一个配置文件并没有被编译进来。这时候,我们的基本上就达成 了。

注意:由于我们这里配置的 dev Profile 是默认激活状态的,所以执行 mvn clean package 和 mvn clean package -Pdev 两个命令的结果是相同的。

Maven入门教程(二)

当然,通过配置 profile ,我们不仅仅可以指定激活不同的配置文件,也可以指定构建使用的JDK版本,以及某些操作系统的参数。

3. 小结

本节中,我们主要介绍了 Maven 的一个属性,叫做 Profile 。通过配置 Profile 我们可以实现构建的环境可移植性,从而大大简化我们在构建过程中的便捷程度,让我们从重复的修改配置的过程中解脱出来。

Maven 生成站点

通常情况下,一个项目很少是由一个人来开发完成的。不同团队间或者项目上线后,实际用户和开发者之间的交流都可以在站点上来完成。用户可以在站点上获取操作教程,用户指南等等,而其他的开发者则可以获取到关于项目的代码报告,问题追踪以及版本发布计划等等。今天我们来介绍一下如何使用 Maven 来生成站点,并且自定义项目的站点。

1. 构建简单的站点

首先我们打开 mall-aggregate 目录下的 pom.xml文件,并且在其中添加 maven-site-plugin 插件。

<plugin>    <groupId>org.apache.maven.plugins</groupId>    <artifactId>maven-site-plugin</artifactId>    <version>3.9.0</version></plugin>

添加完插件之后,Maven 会自动的下载该插件。下载完成后,我们在 mall-aggregate 目录下执行mvn clean site命令。在控制台显示构建完成后,我们可以查看项目的 target 目录中,已经新产生了 site 目录。这个目录就是用来存放站点信息目录。

Maven入门教程(二)

站点生成成功后,我们可以执行mvn site:run命令,在运行这个站点。运行的时候会使用 Maven 内置的 jetty 容器来启动。站点启动后,我们可以在浏览器中输入localhost:8080/来浏览该站点。

Maven入门教程(二)

这时候,我们项目的简单站点就生成好了。在这个简单站点中,我们可以看到关于我们项目的一些信息,比如模块划分,依赖管理,插件管理,项目描述等等信息。有了这个站点,用户与开发者之间,以及开发者与开发者之间就能够更好的进行交流了。

2. 生成项目报告的插件

有的时候,我们还想要在站点里面看到其他的一些信息,诸如,API 文档,代码规约检查,以及代码中是否存在某些 Bug 等等。Maven 也提供了丰富的插件来完成这件事情。这里,我们介绍几个常用的插件。

首先,我们可以打开 Maven 的官网中的插件列表,可以看到不同生命周期对应的不同插件:

Maven入门教程(二)

这里,我们添加三个比较常用的插件作为示例,其他的功能的插件可以根据自身项目的需要来自行添加。

2.1 添加 javadoc 插件

首先我们在插件列表中找到对应的插件,点击进入详情后,可以查看该插件的使用方式和 Maven 坐标。找到坐标后,我们在 pom.xml 文件中加入该坐标:

<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
</plugin>
</plugins>
</reporting>

在插件的 Usage 页面我们可以看到添加该依赖的方式有两种。

Maven入门教程(二)

两种添加依赖方式的区别在于,如果将插件放入到 build 节点下,则需要会生成单独的 javadoc 文档,如果将插件的依赖放在 reporting 节点下,则产生的 javadoc 会作为项目报告的一部分,即会生成在站点的目录中。这里,我们选择的是后面一种,随着站点的生成,产生 javadoc 。

此时我们在 mall-aggregate 目录下执行 mvn clean site 命令。站点生成后,执行mvn site:run 命令启动站点。站点启动成功后,尝试访问站点的地址 localhost:8080。我们可以看到在站点的目录中多了一个 Project Reports 的目录,点开后,我们可以看到 Javadoc 和 Test Javadoc,点击可以查看其产生的内容。

Maven入门教程(二)

2.2 添加 checkstyle 插件

checkstyle 插件可以帮助团队中的各个成员来检查编码规范,并生成检查后的报告。我们首先在 pom.xml 文件中加入 checkstyle 插件的依赖:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
</plugin>

待 Maven 下载该插件完成后,执行命令mvn clean site来重新生成站点。站点生成后,执行mvn site:run命令来重新启动站点。启动后,同样是在 Project Reports 目录下,可以看到新生成的 checkStyle 结果。

Maven入门教程(二)

2.3 添加 jxr 插件

Maven 的 jxr 插件是一个很强大的插件,可以随时查看项目的源代码。相同步骤,首先在 pom.xml 文件中加入 jxr 插件的依赖:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<aggregate>true</aggregate>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

待 Maven 下载该插件完成后,重新生成站点,并重启站点,即可在左边的目录中看到新生成的源码目录,点击后即阅读其中的源码。

Maven入门教程(二)

3. 自定义站点外观

默认情况下,如果用户想要自定义站点的外观,需要在src/site目录下创建 site.xml 文件,在该文件中定义其中的参数和配置。

<project name="ximi-mall">
<!-- 定义左侧banner -->
<bannerLeft>
<name>Sonatype</name>
<src>https://www.imooc.com/static/img/index/logo.png</src>
<href>http://maven.apache.org/</href>
</bannerLeft>
<!-- 定义菜单栏 -->
<body>
<menu ref="reports"/>
</body>
<!-- 定义皮肤 -->
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.9</version>
</skin>
</project>

这里,我们简单配置了 site.xml 文件,重新定义了站点的 Logo,以及站点的皮肤(skin)。重新打开站点后,样式已经发生了很大的变化

这里面的皮肤可以直接在 Maven 的官网中找到皮肤列表。在这其中选择自己喜欢的皮肤类型。

4. 小结

本节中,我们简单介绍了如何使用 Maven 帮助我们来生成自己项目的站点, 以及如何简单装饰自己的站点。有了站点,我们可以和用户以及其他的开发者更好的交流。

Maven 属性与资源过滤

在之前的章节中,我们已经介绍了 Maven 如何使用 Profile 来进行构建。类似的,对于 Maven 来说,还有很多其他的资源或者属性,而这些资源或者属性也都是可以进行过滤的,这一小节中,我们就重点介绍一下在什么情况下,需要过滤这些,并且要如何进行操作。

1. 属性

首先,我们来介绍一下 Maven 的属性特性。其实,在我们之前的章节中,一直都有在使用 Maven 的属性。例如我们在引入 Spring 框架的时候,将 Spring 框架的版本号信息抽象出来,放到 properties 节点中去,在使用这个版本号的时候,可以通过${}来引用。

<properties>
<spring.version>4.0.2.RELEASE</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

我们都知道抽象了spring.version属性之后,可以减少我们很多的工作量,而且也便于我们对 pom.xml 文件的管理。在 Maven 的世界中,这只是其中一种属性。那我们来介绍一下 Maven 的属性的种类。

  • 内置属性: Maven 的内置属性主要有两个,一个是${basedir}用来表示项目的根目录,另一个是${version}用来表示项目的版本号;
  • POM属性: 用来引用 pom.xml 文件中对应元素的值。一般来说,可以用${project.*}来表示,例如:${project.groupId}就是用来表示项目的 groupId 信息;
  • 自定义属性: 这个比较容易理解,就像我们上面例子中的${spring.version}就属于自定义属性的范围;
  • Settings属性: 与 POM 属性类似。通常使用${settings.*}来表示,Settings 属性用来指向 settings.xml 文件中的属性,例如:${settings.localrepository}可以用来表示本地仓库的地址;
  • Java系统属性: 所有 Java 的系统属性都可以通过 Maven 属性来引用。我们在使用之前可以通过mvn help:system命令来查看对应的属性;
  • 环境变量属性: 所有的环境变量属性都可以通过 Maven 属性来引用。通常用 ${env.*}来表示。

我们在很多地方都可以用到 Maven 属性,例如我们的示例项目中,多模块直接互相引用的时候,我们会用到${project.groupId}${project.version},来管理项目内部依赖。会用到${project.basedir}来指定项目配置文件的路径。

2. Profile

这里就是之前章节中讲到的 Profile ,所以在这里,我们就不做过多的介绍,可以移步到《Maven 使用 Profile 构建》一节进行学习。

3. 资源过滤

我们使用 Maven 资源过滤的目的和使用 Profile 的目的很大程度上是类似的,就是为了增强项目构建的可移植性。之前我们在 Profile 的章节中,讲到了在构建项目的时候,激活对应的 Profile 来使用对应的配置,当时我们把配置都放在了配置文件中,因此,如果有多套环境的话,那么配置文件就相应的需要多套。

这里,我们换一种方式来进行资源过滤。在讲 Profile 的章节中,我们使用 mall-order 模块来演示,这次我们换为 mall-delivery 模块来演示。

首先在 src\main\resources目录下添加application.yml文件,用作配置文件。文件中的内容如下:

spring:  datasource:    driver-class-name: ${database.driverClass}    username: ${database.username}    password: ${database.password}    url: ${database.url}    type: com.alibaba.druid.pool.DruidDataSource

这里,可以看到,我们使用了${}的方式来引用属性,这个属性可以定义在pom.xml文件中。

接下来,我们就在pom.xml 文件中配置对应的属性。

<build>    <resources>        <resource>            <directory>src/main/resources</directory>            <filtering>true</filtering>        </resource>    </resources></build><profiles>    <profile>	    <id>dev</id>    	<properties>            <database.driverClass>com.mysql.cj.jdbc.Driver</database.driverClass>            <database.url>jdbc:mysql://localhost:3306/dev</database.url>            <database.username>userNameDev</database.username>            <database.password>passwordDev</database.password>		</properties>    </profile>    <profile>        <id>test</id>        <properties>            <database.driverClass>com.mysql.cj.jdbc.Driver</database.driverClass>            <database.url>jdbc:mysql://localhost:3307/test</database.url>	        <database.username>userNameTest</database.username>            <database.password>passwordTest</database.password>        </properties>        </profile></profiles>

通常情况下,资源过滤是关闭的,如果需要开启,则需要我们手动设置 <filtering>true</filtering>。默认关闭也是为了防止在构建的过程中发生一些不必要的过滤情况。

这里,我们分别配置了开发环境的数据库信息和测试环境的数据库信息(其实也是使用的 Profile 的方式)。其中 properties 节点配置了我们自定义的属性,其与我们刚刚在application.yml文件中配置的占位符是一样的。

接下来,我们进行项目构建可以指定对应的 Profile,执行 Maven 命令mvn clean package -Pdev。构建完成后,我们可以查看target\classes目录下的构建结果,会发现配置文件中的确是用的开发环境的 Profile,目的达成。

spring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    username: userNameDev    password: passwordDev    url: jdbc:mysql://localhost:3306/dev    type: com.alibaba.druid.pool.DruidDataSource

以上的配置,还可以进行一下修改。由于我们平时更多的是在用开发环境的配置,因此,我们可以把开发环境的配置单独放置出来。

<build>	...</build><properties>    <database.driverClass>com.mysql.cj.jdbc.Driver</database.driverClass>    <database.url>jdbc:mysql://localhost:3306/dev</database.url>	<database.username>userNameDev</database.username>    <database.password>passwordDev</database.password></properties><profiles>    <profile>        <id>test</id>        <properties>            <database.driverClass>com.mysql.cj.jdbc.Driver</database.driverClass>            <database.url>jdbc:mysql://localhost:3307/test</database.url>	        <database.username>userNameTest</database.username>            <database.password>passwordTest</database.password>        </properties>        </profile></profiles>

这样修改之后,我们在进行开发环境构建的时候,不需要添加额外的参数,直接执行命令mvn clean package即可正常构建。而当我们需要构建其他环境程序包的时候,则在命令后面添加对应的参数。

4. 小结

本文,我们承接《Maven 使用 Profile 构建》一节,继续介绍 Maven 的属性和资源过滤,学了这两节之后,能够更方便,更明晰的管理 pom.xml 文件中的依赖,也让多环境构建变得更加简单。

发表评论

登录后才能评论
联系客服
联系客服
分享本页
返回顶部