Maven —— 项目依赖版本号管理(pom文件的进阶使用之bom)

本文围绕Maven依赖管理展开。介绍了dependencyManagement在多模块项目中定义依赖版本的作用,以及BOM文件罗列依赖和版本、保证兼容性的特点。阐述了依赖版本冲突时的选定规则,遵循最短最近原则,还讲解了scope为provided的含义及打包影响。

总结图示

dependencyManagement

Maven —— dependencies与dependencyManagement的区别

        在maven多模块项目中,可以在项目主目录下的pom文件 —— 图中的pom(主)中,使用dependencyManagement定义所有模块需要用到的依赖版本。

        dependencyManagement只会影响现有依赖的配置,但不会引入依赖。在pom(主)中严禁直接使用depandencys预定义依赖,否则子model会自动继承depandencys中所有预定义依赖。

         maven的继承与Java相同,单继承,子model中只能出现一个parent标签,对应一个pom文件的dependencyManagement。此时,如果dependencyManagement中预定义太多的依赖,会造成pom文件过长,而且很乱。

BOM(Bill of Materials)

        本质是一个普通的POM文件,只是在这个POM中,罗列的是一个工程的所有依赖和其对应的版本。该文件一般被其它工程使用,当其它工程引用BOM中的依赖时,不用指定具体的版本,会自动使用BOM对应的jar版本。

        BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。

        一个pom文件中可以引用多个bom。

BOM文件示例

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.niceshot</groupId>
    <artifactId>test-BOM</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!--注意-->
    <packaging>pom</packaging>
    <!--注意-->
    <name>Test-BOM</name>
    <description>parent pom</description>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>test</groupId>
                <artifactId>a</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>test</groupId>
                <artifactId>b</artifactId>
                <version>1.0</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>test</groupId>
                <artifactId>c</artifactId>
                <version>1.0</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

BOM引用示例

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.niceshot</groupId>
                <artifactId>test-BOM</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <type>pom</type>
    <!--scope=import只能用在dependencyManagement里面,且仅用于type=pom的dependency-->
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

冲突版本选定规则

        依赖的版本可在多处配置,当出现版本冲突时,具体使用哪一个版本的优先顺序

        1、直接在当前工程中显示指定的版本

        2、parent中配置的父工程使用的版本

        3、在当前工程中通过dependencyManagement引入的BOM清单中的版本,当引入的多个BOM都有对应jar包时,先引入的BOM生效

        4、上述三个地方都没配置,则启用依赖调解dependency mediation

依赖调节遵循 —— 最短最近原则。

最短路径:取决于路径的长短

        A -> B -> C -> D 1.4

        A -> E -> D 1.0

        使用D的1.0版本。

最近原则:取决于依赖的先后

        A -> B -> D 1.1

        A -> C -> D 1.3

        使用D的1.1版本。

scope —— provided

        scope默认为compile,项目在编译,测试,运行阶段都会引入依赖中需要的依赖 。

        provided的意思是:容器中已经provide了这个依赖。provided会认为目标容器已经引入了依赖中需要的依赖(例: 运行和测试 servlet API, 实际项目运行时容器会提供 API)。

        比如,项目ProjectABC 中有一个类叫C,而这个C1中会import这个portal-impl的artifact中的类B,那么在编译阶段,我们肯定需要这个B,否则C通不过编译,因为scope设置为provided,所以编译阶段起作用,所以C正确的通过了编译。测试阶段类似。

        那么最后我们要把ProjectABC部署到Liferay服务器上,这时候,我们到$liferay-tomcat-home\webapps\ROOT\WEB-INF\lib下发现,里面已经有了一个portal-impl.jar了,换句话说,容器已经提供了这个artifact对应的jar。所以,这个C类直接可以用容器提供的portal-impl.jar中的B类,而不会出任何问题。

        实际打包检测发现:当我们用maven install生成最终的构件包ProjectABC.war后,在其下的WEB-INF/lib中,会包含我们被标注为scope=compile的构件的jar包,而不会包含我们被标注为scope=provided的构件的jar包。

<scope>provided</scope>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇宙超级无敌程序媛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值