深入探索Maven:优雅构建Java项目的新方式(二)

Meven高级

1,属性

1.1 属性

1.1.1 问题分析

我们先来分析问题:

如果在父工程中的dependencyManagement标签中对项目中所使用的jar包版本进行了统一的管理,但是如果在标签中有如下的内容:

你会发现,如果我们现在想更新Spring的版本,你会发现我们依然需要更新多个jar包的版本,这样的话还是有可能出现漏改导致程序出问题,而且改起来也是比较麻烦。

1.1.2 解决步骤

步骤1:父工程中定义属性
xml 复制代码
<properties>
    <spring.version>5.2.10.RELEASE</spring.version>
    <junit.version>4.12</junit.version>
    <mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>
步骤2:修改依赖的version
xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>

此时,我们只需要更新父工程中properties标签中所维护的jar包版本,所有子项目中的版本也就跟着更新。当然除了将spring相关版本进行维护,我们可以将其他的jar包版本也进行抽取,这样就可以对项目中所有jar包的版本进行统一维护,如:

xml 复制代码
<!--定义属性-->
<properties>
    <spring.version>5.2.10.RELEASE</spring.version>
    <junit.version>4.12</junit.version>
    <mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>

1.2 配置文件加载属性

Maven中的属性我们已经介绍过了,现在也已经能够通过Maven来集中管理Maven中依赖jar包的版本。但是又有新的需求,就是想让Maven对于属性的管理范围能更大些,比如我们之前项目中的jdbc.properties,这个配置文件中的属性,能不能也来让Maven进行管理呢?

答案是肯定的,具体的实现步骤为:

步骤1:父工程定义属性
xml 复制代码
<properties>
   <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
</properties>
步骤2:jdbc.properties文件中引用属性

在jdbc.properties,将jdbc.url的值直接获取Maven配置的属性

properties 复制代码
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
步骤3:设置maven过滤文件范围

Maven在默认情况下是从当前项目的src\main\resources下读取文件进行打包。现在我们需要打包的资源文件是在maven_02_ssm下,需要我们通过配置来指定下具体的资源目录。

xml 复制代码
<build>
    <resources>
        <!--设置资源目录-->
        <resource>
            <directory>../maven_02_ssm/src/main/resources</directory>
            <!--设置能够解析${},默认是false -->
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

说明 :directory路径前要添加../的原因是maven_02_ssm相对于父工程的pom.xml路径是在其上一层的目录中,所以需要添加。

修改完后,注意maven_02_ssm项目的resources目录就多了些东西,如下:

步骤4:测试是否生效

测试的时候,只需要将maven_02_ssm项目进行打包,然后观察打包结果中最终生成的内容是否为Maven中配置的内容。

上面的属性管理就已经完成,但是有一个问题没有解决,因为不只是maven_02_ssm项目需要有属性被父工程管理,如果有多个项目需要配置,该如何实现呢?

方式一:

xml 复制代码
<build>
    <resources>
        <!--设置资源目录,并设置能够解析${}-->
        <resource>
            <directory>../maven_02_ssm/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>../maven_03_pojo/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        ...
    </resources>
</build>

可以配,但是如果项目够多的话,这个配置也是比较繁琐

方式二:

xml 复制代码
<build>
    <resources>
        <!--
			${project.basedir}: 当前项目所在目录,子项目继承了父项目,
			相当于所有的子项目都添加了资源目录的过滤
		-->
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

说明 :打包的过程中如果报如下错误:

原因就是Maven发现你的项目为web项目,就会去找web项目的入口web.xml[配置文件配置的方式],发现没有找到,就会报错。

解决方案1:在maven_02_ssm项目的src\main\webapp\WEB-INF\添加一个web.xml文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
</web-app>

解决方案2: 配置maven打包war时,忽略web.xml检查

xml 复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.2.3</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
</build>

上面我们所使用的都是Maven的自定义属性,除了${project.basedir},它属于Maven的内置系统属性。

在Maven中的属性分为:

  • 自定义属性(常用)
  • 内置属性
  • Setting属性
  • Java系统属性
  • 环境变量属性

    具体如何查看这些属性:

在cmd命令行中输入mvn help:system

具体使用,就是使用 ${key}来获取,key为等号左边的,值为等号右边的,比如获取红线的值,对应的写法为 ${java.runtime.name}

1.3 版本管理

关于这个版本管理解决的问题是,在Maven创建项目和引用别人项目的时候,我们都看到过如下内容:

这里面有两个单词,SNAPSHOT和RELEASE,它们所代表的含义是什么呢?

我们打开Maven仓库地址https://mvnrepository.com/

在我们jar包的版本定义中,有两个工程版本用的比较多:

  • SNAPSHOT(快照版本)
    • 项目开发过程中临时输出的版本,称为快照版本
    • 快照版本会随着开发的进展不断更新
  • RELEASE(发布版本)
    • 项目开发到一定阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的
    • 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本

除了上面的工程版本,我们还经常能看到一些发布版本:

  • alpha版:内测版,bug多不稳定内部版本不断添加新功能
  • beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能
  • 纯数字版

对于这些版本,大家只需要简单认识下即可。

2,多环境配置与应用

我们要了解两个内容,分别是多环境开发跳过测试

2.1 多环境开发

  • 我们平常都是在自己的开发环境进行开发,
  • 当开发完成后,需要把开发的功能部署到测试环境供测试人员进行测试使用,
  • 等测试人员测试通过后,我们会将项目部署到生成环境上线使用。
  • 这个时候就有一个问题是,不同环境的配置是不相同的,如不可能让三个环境都用一个数据库,所以就会有三个数据库的url配置,
  • 我们在项目中如何配置?
  • 要想实现不同环境之间的配置切换又该如何来实现呢?

maven提供配置多种环境的设定,帮助开发者在使用过程中快速切换环境。具体实现步骤:

步骤1:父工程配置多个环境,并指定默认激活环境

xml 复制代码
<profiles>
    <!--开发环境-->
    <profile>
        <id>env_dep</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
        </properties>
        <!--设定是否为默认启动环境-->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!--生产环境-->
    <profile>
        <id>env_pro</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
        </properties>
    </profile>
    <!--测试环境-->
    <profile>
        <id>env_test</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
        </properties>
    </profile>
</profiles>

步骤2:执行安装查看env_dep环境是否生效

查看到的结果为:

步骤3:切换默认环境为生产环境

xml 复制代码
<profiles>
    <!--开发环境-->
    <profile>
        <id>env_dep</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
        </properties>
    </profile>
    <!--生产环境-->
    <profile>
        <id>env_pro</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
        </properties>
        <!--设定是否为默认启动环境-->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!--测试环境-->
    <profile>
        <id>env_test</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
        </properties>
    </profile>
</profiles>

步骤4:执行安装并查看env_pro环境是否生效

查看到的结果为jdbc:mysql://127.2.2.2:3306/ssm_db

虽然已经能够实现不同环境的切换,但是每次切换都是需要手动修改,如何来实现在不改变代码的前提下完成环境的切换呢?

步骤5:命令行实现环境切换

步骤6:执行安装并查看env_test环境是否生效

查看到的结果为jdbc:mysql://127.3.3.3:3306/ssm_db

所以总结来说,对于多环境切换只需要两步即可:

  • 父工程中定义多环境

    xml 复制代码
    <profiles>
    	<profile>
        	<id>环境名称</id>
            <properties>
            	<key>value</key>
            </properties>
            <activation>
            	<activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        ...
    </profiles>
  • 使用多环境(构建过程)

    mvn 指令 -P 环境定义ID[环境定义中获取]
    

2.2 跳过测试

前面在执行install指令的时候,Maven都会按照顺序从上往下依次执行,每次都会执行test,

对于test来说有它存在的意义,

  • 可以确保每次打包或者安装的时候,程序的正确性,假如测试已经通过在我们没有修改程序的前提下再次执行打包或安装命令,由于顺序执行,测试会被再次执行,就有点耗费时间了。
  • 功能开发过程中有部分模块还没有开发完毕,测试无法通过,但是想要把其中某一部分进行快速打包,此时由于测试环境失败就会导致打包失败。

遇到上面这些情况的时候,我们就想跳过测试执行下面的构建命令,具体实现方式有很多:

方式一:IDEA工具实现跳过测试

图中的按钮为Toggle 'Skip Tests' Mode,

Toggle翻译为切换的意思,也就是说在测试与不测试之间进行切换。

点击一下,出现测试画横线的图片,如下:

说明测试已经被关闭,再次点击就会恢复。

这种方式最简单,但是有点"暴力",会把所有的测试都跳过,如果我们想更精细的控制哪些跳过哪些不跳过,就需要使用配置插件的方式。

方式二:配置插件实现跳过测试

在父工程中的pom.xml中添加测试插件配置

xml 复制代码
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <skipTests>false</skipTests>
                <!--排除掉不参与测试的内容-->
                <excludes>
                    <exclude>**/BookServiceTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试

excludes:哪些测试类不参与测试,即排除,针对skipTests为false来设置的

includes: 哪些测试类要参与测试,即包含,针对skipTests为true来设置的

方式三:命令行跳过测试

使用Maven的命令行,mvn 指令 -D skipTests

注意事项:

  • 执行的项目构建指令必须包含测试生命周期,否则无效果。例如执行compile生命周期,不经过test生命周期。
  • 该命令可以不借助IDEA,直接使用cmd命令行进行跳过测试,需要注意的是cmd要在pom.xml所在目录下进行执行。

3,私服

我们主要了解的内容是:

  • 私服简介
  • 私服仓库分类
  • 资源上传与下载

首先来说一说什么是私服?

3.1 私服简介

团队开发现状分析

(1)张三负责ssm_crm的开发,自己写了一个ssm_pojo模块,要想使用直接将ssm_pojo安装到本地仓库即可

(2)李四负责ssm_order的开发,需要用到张三所写的ssm_pojo模块,这个时候如何将张三写的ssm_pojo模块交给李四呢?

(3)如果直接拷贝,那么团队之间的jar包管理会非常混乱而且容器出错,这个时候我们就想能不能将写好的项目上传到中央仓库,谁想用就直接联网下载即可

(4)Maven的中央仓库不允许私人上传自己的jar包,那么我们就得换种思路,自己搭建一个类似于中央仓库的东西,把自己的内容上传上去,其他人就可以从上面下载jar包使用

(5)这个类似于中央仓库的东西就是我们接下来要学习的私服

所以到这就有两个概念,一个是私服,一个是中央仓库

私服:公司内部搭建的用于存储Maven资源的服务器

远程仓库:Maven开发团队维护的用于存储Maven资源的服务器

所以说:

  • 私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题

搭建Maven私服的方式有很多,我们来介绍其中一种使用量比较大的实现方式:

3.2 私服安装

步骤1:下载

步骤2:启动Nexus

使用cmd进入到解压目录下的nexus-3.30.1-01\bin,执行如下命令:

nexus.exe /run nexus

看到如下内容,说明启动成功。

步骤3:浏览器访问

访问地址为:

http://localhost:8081

步骤4:首次登录重置密码

输入用户名和密码进行登录,登录成功后,出现如下页面

点击下一步,需要重新输入新密码,为了和后面的保持一致,密码修改为admin

设置是否运行匿名访问

点击完成

至此私服就已经安装成功。如果要想修改一些基础配置信息,可以使用:

  • 修改基础配置信息
    • 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口。
  • 修改服务器运行配置信息
    • 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间。

3.3 私服仓库分类

私服资源操作流程分析:

(1)在没有私服的情况下,我们自己创建的服务都是安装在Maven的本地仓库中

(2)私服中也有仓库,我们要把自己的资源上传到私服,最终也是放在私服的仓库中

(3)其他人要想使用你所上传的资源,就需要从私服的仓库中获取

(4)当我们要使用的资源不是自己写的,是远程中央仓库有的第三方jar包,这个时候就需要从远程中央仓库下载,每个开发者都去远程中央仓库下速度比较慢(中央仓库服务器在国外)

(5)私服就再准备一个仓库,用来专门存储从远程中央仓库下载的第三方jar包,第一次访问没有就会去远程中央仓库下载,下次再访问就直接走私服下载

(6)前面在介绍版本管理的时候提到过有SNAPSHOTRELEASE,如果把这两类的都放到同一个仓库,比较混乱,所以私服就把这两个种jar包放入不同的仓库

(7)上面我们已经介绍了有三种仓库,一种是存放SNAPSHOT的,一种是存放RELEASE还有一种是存放从远程仓库下载的第三方jar包,那么我们在获取资源的时候要从哪个仓库种获取呢?

(8)为了方便获取,我们将所有的仓库编成一个组,我们只需要访问仓库组去获取资源。

所有私服仓库总共分为三大类:

宿主仓库hosted

  • 保存无法从中央仓库获取的资源
    • 自主研发
    • 第三方非开源项目,比如Oracle,因为是付费产品,所以中央仓库没有

代理仓库proxy

  • 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库

仓库组group

  • 将若干个仓库组成一个群组,简化配置
  • 仓库组不能保存资源,属于设计型仓库

3.4 本地仓库访问私服配置

  • 我们通过IDEA将开发的模块上传到私服,中间是要经过本地Maven的
  • 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码
  • 私服中的仓库很多,Maven最终要把资源上传到哪个仓库?
  • Maven下载的时候,又需要携带用户名和密码到私服上找对应的仓库组进行下载,然后再给IDEA

上面所说的这些内容,我们需要在本地Maven的配置文件settings.xml中进行配置。

步骤1:私服上配置仓库

说明:

第5,6步骤是创建itheima-snapshot仓库

第7,8步骤是创建itheima-release仓库

步骤2:配置本地Maven对私服的访问权限

xml 复制代码
<servers>
    <server>
        <id>itheima-snapshot</id>
        <username>admin</username>
        <password>admin</password>
    </server>
    <server>
        <id>itheima-release</id>
        <username>admin</username>
        <password>admin</password>
    </server>
</servers>

步骤3:配置私服的访问路径

xml 复制代码
<mirrors>
    <mirror>
        <!--配置仓库组的ID-->
        <id>maven-public</id>
        <!--*代表所有内容都从私服获取-->
        <mirrorOf>*</mirrorOf>
        <!--私服仓库组maven-public的访问路径-->
        <url>http://localhost:8081/repository/maven-public/</url>
    </mirror>
</mirrors>

为了避免阿里云Maven私服地址的影响,建议先将之前配置的阿里云Maven私服镜像地址注释掉,等练习完后,再将其恢复。

至此本地仓库就能与私服进行交互了。

3.5 私服资源上传与下载

本地仓库与私服已经建立了连接,接下来我们就需要往私服上上传资源和下载资源,具体的实现步骤为:

步骤1:配置工程上传私服的具体位置

xml 复制代码
 <!--配置当前工程保存在私服中的具体位置-->
<distributionManagement>
    <repository>
        <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
        <id>itheima-release</id>
         <!--release版本上传仓库的具体地址-->
        <url>http://localhost:8081/repository/itheima-release/</url>
    </repository>
    <snapshotRepository>
        <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
        <id>itheima-snapshot</id>
        <!--snapshot版本上传仓库的具体地址-->
        <url>http://localhost:8081/repository/itheima-snapshot/</url>
    </snapshotRepository>
</distributionManagement>

步骤2:发布资源到私服

或者执行Maven命令

mvn deploy

注意:

要发布的项目都需要配置distributionManagement标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可。

发布成功,在私服中就能看到:

现在发布是在itheima-snapshot仓库中,如果想发布到itheima-release仓库中就需要将项目pom.xml中的version修改成RELEASE即可。

如果想删除已经上传的资源,可以在界面上进行删除操作:

如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。

至此私服的搭建就已经完成,相对来说有点麻烦,但是步骤都比较固定,后期大家如果需要的话,就可以参考上面的步骤一步步完成搭建即可。

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

相关推荐
csdn_金手指10 分钟前
docker 通过Dockerfile自定义的镜像部署Springboot项目
spring boot·docker·容器
jokerest12317 分钟前
pwn——test_your_nc1——测试
开发语言·php
小宋102125 分钟前
实现Excel文件和其他文件导出为压缩包,并导入
java·javascript·excel·etl
碧海蓝天202229 分钟前
接上一主题,C++14中如何设计类似于std::any,使集合在C++中与Python一样支持任意数据?
开发语言·c++·python
guihong00429 分钟前
JAVA面试题、八股文学习之JVM篇
java·jvm·学习
QQ_11543203131 分钟前
基于Java+SpringBoot+Mysql在线简单拍卖竞价拍卖竞拍系统功能设计与实现九
java·spring boot·mysql·毕业设计·毕业源码·竞拍系统·竞拍项目
醉颜凉33 分钟前
计算(a+b)/c的值
java·c语言·数据结构·c++·算法
CQXXCL34 分钟前
MySQL-学习笔记
笔记·学习·mysql
周杰伦fans35 分钟前
Java与C#
java·开发语言·c#