Maven系列:pom&坐标详解

maven系列

阅读本文大约需要10分钟

Maven中的pom文件

Maven项目的核心是pom(project object model)文件

Maven项目结构

在这里插入图片描述

  • src/main
    • java 主代码目录
    • resouces 资源文件目录
  • src/test
    • java 测试代码目录
    • resouces 测试资源文件目录

maven的项目结构是是约定好的, 我们不是必须每次按照maven的约定的结构去新建项目,也可以通过maven提供的骨架生成我们需要的项目

pom文件

mavenpom文件的整体结构

<?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>
		    <groupId>cn.bread</groupId>
		    <artifactId>mtest</artifactId>
		    <version>1.0-SNAPSHOT</version>
		    <packaging>jar</packaging>
		    <name>mtest</name>
    </project> 
Maven的坐标信息
  • modelVersion
    定义当前项目的遵循的模型版本
  • groupid
    当前项目的实际项目信息,不应该对应到公司或者组织,应该对应到公司或者组织下边某一实际项目
  • artifactId
    当前项目的模块信息
  • version
    当前模块的版本信息
  • packaging
    模块的打包类型,不定义packageing时,默认为jar
  • classifier
    用来定义输出一些附属构件的,也可以理解为一套源码,输出成两套构件
  • name
    当前项目的一些描述信息
modelVersiongroupidartifactIdversionpackagingclassifiername
3.0之后必须定义必须定义必须定义必须定义不定义默认jar不能直接定义非必须定义

小结: 在maven项目中,项目结构是固定的,pom文件是核心配置文件,在pom文件中配置当前项目的坐标信息,通过坐标信息就可以定位到这个项目的位置,并且了解到一个项目坐标的定义必须有三个要素,

Maven 依赖详解

日常项目开发中,我们需要引入第三方的依赖,在传统的项目中,我们只能挨个网站去找,在maven提供了引入依赖的方法

在dependencies元素中,使用 dependency 元素引入依赖

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
        </dependency>
<dependencies>
  • groupid artifactId version
    maven的坐标信息和版本信息,组合定义唯一的仓库的依赖坐标信息
  • type
    type是指依赖的类型,对应坐标的 packageing 默认为jar
  • scope
    scope是指依赖范围,指当前依赖的作用域,默认为compiler
  • optional
    标记依赖是否可选,默认为false,
  • exclusions
    排除依赖
依赖范围(scope)

maven项目目录分为主代码目录和测试代码目录
maven项目编译时分为三种classpath

  1. 编译classpath
    主代码编译,也可以认为是 src/java 目录下代码编译范围
  2. 测试classpath
    测试代码编译 src/test 目录下代码编译范围
  3. 运行classpath
    主代码运行,可以理解为 打完包的class文件和lib

依赖范围是用来控制依赖于三种classpath的关系。
依赖范围

  • complie
    编译依赖范围,在三种依赖范围都有效
  • test
    测试依赖范围,在测试依赖范围和运行依赖有效
  • provided
    已提供依赖范围,项目在编译和测试时有用,但是在运行时是不必要的, 因为容器或者环境已经提供了该依赖,最常见的就是tomcat容器
  • runtime
    运行时依赖,该依赖范围对运行和测试时有用,对编译时没用,比如mysql的驱动,在编译时,并没有链接数据库,在实际运行或者测试用例的过程中才会链接数据库,使用驱动包
  • system
    系统级别依赖,使用依赖,必须使用systempath显示声明依赖位置,一般是用于和操作系统绑定
  • import
    导入依赖,在存在继承关系的pom中,子pom引入父级pom时使用

依赖范围表说明

编译 classpath测试classpath运行classpath例如
complieYYYspring-core
testNYNjunit
providedYYNtomcat等web容器的 servlet-api
runtimeNYYJDBC驱动
systemYYN一般是本地有不用导入仓库的

以下分为别5种依赖范围的运行情况,我建议使用web项目打包观察
在这里插入图片描述

传递性依赖

在实际项目开发中,使用某一个依赖时,该依赖有可能又依赖于别人。
例如:项目A依赖 spring-core,;spring-core又依赖于spring-jcl,那么spring-jcl就是项目A的传递性依赖
传递性依赖
maven引入传递性依赖机制,使得我们在项目中,不需要关心第三方类库的的依赖,也不必担心引入多余的依赖。maven会自动帮我们解析pom,将间接性依赖引入进来

传递性依赖依赖范围

假设A依赖于B,B又依赖于C ,那么A对于B来说就是第一依赖,C对于B来说就是第二依赖,A对于C来说就是传递性依赖
在这里插入图片描述

传递性依赖范围表

第二依赖范围
compilertestprovidedruntime
第一依赖范围compilercompiler不传递不传递runtime
testtest不传递不传递test
providedprovided不传递providedprovided
runtimeruntime不传递不传递rumtime
  • 第二依赖范围是 complie ,那么传递性依赖范围就是和第一依赖范围保持一致;例:第二范围是 complie ,第一依赖是test, 那么传递性依赖就是test, 第一依赖是complile ,那么传递性依赖就是complile
  • 第二依赖范围是 test时,依赖不进行传递
  • 第二依赖范围是provided 时,只传递 第一依赖范围为 provided 的依赖,并且 依赖范围为 provided
  • 第二依赖范围是 runtime 时, 传递性依赖范围与 第一依赖范围保持一致 ;第一依赖范围为complie除外,compile为runtime

了解依赖的依赖范围,和传递性依赖范围,可以很好解决我们项目在实际使用依赖臃肿的问题, 不是所有依赖必须配置为编译时依赖

依赖调节

假如
项目 A
引入了 A - > B ->C - X (1.0)
引入了 A - > D - X (2.0)
实际项目中用到的依赖X 用的是哪个版本呢?

  • 依赖调解的第一原则,最短路径原则
    因为 A - > D -> X 路径小于 A -> B -> C -> X ,因此 X (2.0)会被解析
  • 依赖调解的第二原则,第一声明优先
    假如 A- > D -> Y (1.0) 和 A -> C -> Y (2.0) 路径相同的情况下,谁先申明谁被解析,因此,Y (1.0)会被解析

在引入第一依赖中,版本号高的会被解析,但是不建议声明两个版本不同的依赖,在存在传递性依赖时,按照调解第一原则和第二原则进行加载

可选依赖

通过 optional 来标记当前依赖是否为可选依赖
在实际项目中有场景, A 依赖于B B依赖于 X 和 Y ;如果 X 和 Y 的依赖范围为 complier,那A的对于X和Y 的依赖范围也是 compiler,但是实际A项目中使用不到 X和Y ,就把X和Y 标记为 可选依赖,可选依赖不会进行传递
在这里插入图片描述
在这里插入图片描述
mysql-connector-java 没有被传递

排除依赖&归类依赖
  • 排除依赖
    排除依赖通过 exclusions 标签来排除依赖

在项目中,可能需要排除第三方依赖的传递性依赖,根据项目情况手动引入或者不引入,如果存在多级引入时,那么当前排除的依赖的引入的所有依赖,
在这里插入图片描述

fastjson 和 zookeeper被排除掉

  • 归类依赖
    归类依赖,就是把相同组织下同一项目的不同模块,按照同一版本号一起引入依赖

在项目使用过程中,用到spring 或者 netty 的框架时,往往需要依赖的模块比较多,如果每个模块按照不同的版本,引入到项目中,有可能造成框架不可用,或者版本不同的引起的BUG,大的开源框架迭代基本上所有模板一起迭代的,为了保障项目的依赖统一。通过全局属性,设定依赖的版本号
在这里插入图片描述

优化依赖

实际项目使用中,我们优化依赖时需要明白项目中到底引入哪些依赖,通过以下命令便可以分析;
通过以下命令来查看

  • mvn dependency:list
    查看当前项目的依赖列表
    在这里插入图片描述

  • mvn dependency:tree
    查看当前项目的依赖树;树形展示 在这里插入图片描述

  • mvn dependency:analyze
    Used undeclared dependencies found
    项目中使用的依赖但是没有显式声明
    Unused declared dependencies found
    项目中声明的依赖但是没有使用到

重点看提示信息, Used undeclared dependencies found & Unused declared dependencies found在这里插入图片描述

坐标和依赖是maven比较核心的两个概念,弄懂依赖机制,就能解决我们项目中实际的遇到的引入问题

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值