Maven基础知识

本文参考B站UP主:DT课堂原名颜群 的maven视频写出。
1.maven作用
a.管理jar包
    i.增加第三方包
    ii.自动处理jar包之间的依赖关系(自动关联下载,版本自动适配)
b.将项目拆分成多个模块
 
2.maven概念:
    基于Java平台的自动化构建工具
    (其他还有gradle)
    可以
    清理:删除编译的结果,为重新编译做准备
    编译:java->class
    测试:单元测试, 开发人员与测试人员交互
    报告:将测试的结果进行显示
    打包:用于安装部署(java项目->jar , web项目->war)
    安装:将打成的包放到本地仓库,供其他项目使用
    部署:将打成的包放到服务器上准备运行
    --将java、js、jsp等各个文件进行筛选、组装变成一个可运行的项目
 
自动化构建工具maven:将原材料(java、js、css、html、图片)->产品(可发布项目)
 
本地仓库(先在本地仓库下载,一般是个人的仓库)
私服(nexus,一般是公司所有人共享的仓库,本地仓库没有时去私服仓库找)
中央仓库(私人仓库没有时再联网去中央仓库下载)
中央仓库镜像(对中央仓库分流,减轻其压力)
 
    eclipse中部署的web项目可以运行
    将eclipse中的项目直接复制到tomcat/webapps中则无法运行
    原因:eclipse中的项目,在部署时会生成一个对应的部署项目(在wtowebapps中),区别在于:部署项目的项目其实是没有源码src的(.java文件)只有编译后的class文件和jsp文件。而直接复制粘贴的项目其目录结构和tomcat中的部署项目结构是不一样的,所以tomcat无法直接运行eclipse中直接复制过来的项目。
    要想用eclipse部署则需要打包项目为war,复制到tomcat的webapps中。或者通过eclipse中的Add and remove按钮进行部署
4.使用maven
    约定优于配置(指文件路径格式)
    硬编码方式:job.setPath("d:\\abc");
    配置方式:job
        conf.xml-><path>d:\\abc</path>
    约定方式:job使用默认值d:\\abc
maven约定的目录结构:
    项目
        pom.xml:项目对象模型(与src同级的)
        --target:项目编译后生成的文件
        --src
            --main:程序功能代码
                --java:Java代码
                --resources:资源代码、配置代码
            --test:测试代码
                --java
                --resources
 
(1)、pom配置:
i.如何在仓库中确定唯一模块
 
<project xmlns="html://xxxxx">
<!-- 下面是自己将要开发的项目配置,发布时将按照这个配置发布到相应位置 -->
<groupId>org.lanqiao(域名翻转).maven(大的项目名)</groupId>
<groupId>域名翻转.模块名(大的项目名)</groupId>
 
<artifactId>子模块</artifactId>
<artifactId>HelloWorld</artifactId>
 
<version>版本号</version>
<version>0.0.1-SNAPSHOT</version>
 
<name>起名字(一般就用子模块名)</name>
<name>HelloWorld</name>
 
<!-- 下面是依赖 -->
<dependencies>
    <!-- dependency可以有多个 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.0</version>
        <scope>test</scope>
    </dependency>
    <!-- 可以去百度搜索maven和jar包,点开里面可以直接复制 -->
    <dependency>
        <groupId>域名翻转.模块名</groupId>
        <artifactId>子模块</artifactId>
        <version>版本号</version>
        <scope>依赖的范围默认(compile)</scope>
    </dependency>
</dependencies>
<!--
A中的某些类需要使用B中的某些类,则称为A依赖于B
在Maven某些项目中,如果要使用 一个当时存在的Jar或模块,则可通过依赖实现(去本地仓库、中央仓库去寻找)
-->
 
</project>
(2)、编译运行
cmd进入src文件夹,然后运行命令mvn compile
 
(3)、mvn常见命令
mvn compile 编译 --只编译main目录中的java文件
mvn test 测试
mvn package 打包为jar/war/pom(通过测试才能打包)
mvn install 将开发的模块放入本地仓库,供其他模块使用
mvn clean 清理编译后的产物(清除target文件夹,不会影响本地仓库)
install上传到本地仓库的文件需要手动删除
运行mvn命令必须在pom.xml文件所在的目录(指src)
 
(4)、maven在编译(编译main,指mvn compile)、测试(指执行测试mvn test)、运行(指部署)项目时各自使用一个classPath
(5)、依赖的范围、有效性:
指依赖中<scope>标签的取值
如果为compile,那么编译(指编译主程序main时),测试(指执行测试mvn test),运行(部署时)时都可以找到依赖的jar包
为test时,那么编译和运行的时候都拿不到所依赖的jar包,只有测试拿得到所依赖的jar包(比如测试工具JUnit)
为provided时,那么编译和测试时都可以拿到,只有运行时拿不到。(比如开发与测试Servlet)(因为只有在编译和测试时用得到servlet-api.jar,运行时是在tomcat中,tomcat中自带servlet-api.jar,不需要maven提供jar包)
 
(6).依赖排除
前提:项目需要A.jar,A.jar依赖B.jar,maven会自动引入B.jar
但我们只想要A.jar时使用依赖排除
比如:spring-context.jar依赖spring-aop.jar和spring-beans.jar等,但我只想要spring-context.jar,所以就用如下配置
< dependency >
 
    < groupId > org.springframework </ groupId >
    < artifactId > spring-context </ artifactId >
    < version > 5.2.4.RELEASE </ version >
 
    <!-- 排除依赖 beans aop-->
    < exclusions >
        < exclusion >
            <!-- 如果不知道怎么写就上 maven 官网搜索相关 jar 包并复制粘贴 -->
            < groupId > org.springframework </ groupId >
            < artifactId > spring-beans </ artifactId >
        </ exclusion >
        <!-- 可以排除多个 -->
        < exclusion >
            < groupId > org.springframework </ groupId >
            < artifactId > spring-aop </ artifactId >
        </ exclusion >
    </ exclusions >
 
</ dependency >
 
(7)依赖的传递性
A.jar依赖B.jar,B.jar依赖C.jar
但要使A.jar依赖C.jar,必须使B.jar依赖于C.jar的范围是complie
 
(8)多个maven模块(项目)之间如何依赖:
比如:要使新的A模块依赖已开发好的B模块,需要以下几个步骤:
i.把B模块 install 到本地仓库
ii.把B模块添加到A模块:
<!--在本项目(A模块)中编写如下依赖(编写依赖B模块)-->
<dependency>
    <!--以下内容可直接复制粘贴B模块的pom.xml配置-->
    <groupId>B模块所属的域名翻转.模块名</groupId>
    <artifactId>B模块名</artifactId>
    <version>B模块的版本号</version>
</dependency>
 
(9)依赖原则(为了防止冲突)
a.最短路径优先原则:
以下图HelloWorldTime模块为例:
HelloWorldTime依赖最近的Junit3.8
b.路径长度相同:
    i.在同一个pom.xml文件中有2个相同的依赖: (严格禁止这种写法)
    在pom.xml中越靠后则优先级越高,后面的依赖会覆盖前面的
    比如:下面的配置,优先选择junit4.0
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.0</version>
        <scope>test</scope>
    </dependency>
 
    ii.如果是不同的pom.xml中有相同的依赖,则先声明的依赖会覆盖后声明的依赖。
    例如下图所示:以HelloWorldTime模块为例
 
    下图是HelloWorldTime的pom.xml文件的依赖配置:
    (前提:HelloWorld中没有配置依赖commons-io)
    优先选择在前面声明的依赖模块的pom.xml文件中的jar包
    最终HelloWorldTime模块选择的是HelloWorld2x模块中依赖的commons-io2.4.jar
(10).通过Maven统一jdk版本
i.在模块的pom.xml中配置(只在eclipse中的模块pom.xml中有效)
<!--以下的数字可以改为12、1.8、11等,可直接复制<profiles>标签内容到<project>标签中-->
<project>
    <profiles>
        <profile>
            <id>起一个名字</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.7</jdk>
            </activation>
            <properties>
                < maven.compiler.source>1.7</maven.compiler.source>
                <maven.compiler.target>1.7</ maven.compiler.target>
                <maven.compiler.compilerVersion>1.7</ maven.compiler.compilerVersion>
            </properties>
        </profile>
    </profiles>
</project>
ii.在模块的pom.xml中配置(修改当前项目使用的jdk版本,IDEA与eclipse通用)
<!--以下的数字可以改为12、1.8、11等,可直接复制<build>标签内容到<project>标签中-->
<project>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <!-- <version>3.7.0</version> -->  
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>
iii.在本地maven仓库配置的settings.xml文件中添加配置
在settings.xml文件中找到有<profile>标签的地方,加上如下配置。配置jdk版本为1.8
<profile>
    <id>jdk-1.8</id>    
    <activation>  
        <activeByDefault>true</activeByDefault>    
        <jdk>1.8</jdk>    
    </activation>    
    <properties>    
        < maven.compiler.source>1.8</ maven.compiler.source>    
        < maven.compiler.target>1.8</ maven.compiler.target>    
    </properties>    
</profile>
 
(11)依赖的继承
与依赖的传递区别:A模块继承B模块是指:A可以使用B的所有依赖,不需要看B中的依赖是否有compile范围
想要实现依赖继承有三个步骤
1、确保被继承的父工程打包方式为pom,并且要在父工程的pom.xml文件中配置依赖
在父工程<project>标签中添加:
< packaging > pom </ packaging >
<!--下面< modules >是聚合配置(idea会自动添加,可以省略),具体讲解在第13点-->
< modules >
    < module > 子工程1 名字 </ module >
    < module > 子工程2 名字 </ module >
    < module > 子工程3名字 </ module >
</ modules >
配置依赖(父工程的依赖需要写在<dependencyManagement>标签下):
在之前的<dependencies>标签外套一个<dependencyManagement>标签,具体如下:
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.4.RELEASE</version>
        </dependency>
    </dependencies>
</dependencyManagement>
2、在子工程pom.xml里面配置父工程的坐标,建立继承关系
在子工程的<project>标签中添加
<artifactId>子工程名</artifactId>
<!--当域名翻转.模块名与版本和父工程一样时,可以不填写groupId与version-->
<!--定位父工程坐标-->
<parent>
    <artifactId>父工程名</artifactId>
    <groupId>父工程域名翻转.模块名</groupId>
    <version>父工程版本</version>
    <!--需要在<parent>中写<relativePath>定位父工程的pom.xml相对路径-->
    <relativePath>../父工程名/pom.xml</relativePath>
</parent>
3、在子工程的pom.xml里面声明要使用到父工程里面的哪些依赖
(不用再声明继承的版本号<version>和范围<scope>)
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
</dependencies>
 
优点和区别:
统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,才能保证测试的和发布的是相同的成果,因此,在顶层pom中定义共同的依赖关系。同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。
dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
 
 
(12)快捷更改依赖的版本号,统一编码
i.统一编码:(注意,不是放在pom.xml的<project>标签中,而是放在最外面)
<properties> 
    <!-- 文件拷贝时的编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <!-- 编译时的编码 -->
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding> 
</properties>
 
不过有时候需要更改依赖的版本号,这需要在pom文件里面找很久,还有就是一个一个的改很麻烦,有种便利的方法:
还可以结合 依赖继承统一版本/编码,更加实用
 
(13)Maven聚合
Maven项目能识别的:自身包含的、本地仓库的。
假设Module2依赖Module1,则在执行Module2前必须先将Module1加入到本地仓库(用install命令),之后才能执行Module2。
以上前置工程的install操作,可以交由“聚合”一次性搞定。
通过聚合可以把多个工程合起来
 
聚合的使用:
在一个总工程中配置(总工程只能为pom打包方式)
假设总工程与子工程的目录结构如下(自己建立的路径,不是仓库的路径):
    --Module(总工程)
        --Module1(子工程1)
    --Module2(子工程2)
    --Module3(子工程3)
则在Module工程的pom.xml的<project>中添加的配置如下:
<packaging>pom</packaging>
<modules>
    <!--module中填写子工程相对于总工程的位置(在自己建立的路径上找,不要去仓库中找,没有的),相对路径与子工程名-->
    <module>Module1</module>
    <module>../Module2</module>
    <module>../Module3</module>
</modules>
然后在Module工程执行test,package,install等命令时会自动对Module1等所有子工程执行相同操作
所以配置好聚合后,就不用管先为哪一个工程执行install命令了,因为系统会自动根据依赖的关系去自动执行所有子工程。
注意:聚合的依赖关系遵守依赖的传递规则
5.maven生命周期
假设生命周期中的命令顺序为:a->b->c->d->e
生命周期和构建的关系:即执行一个命令时会把之前的命令全部按顺序先执行完毕,再执行该命令。
比如:
当执行c命令,则实际执行的命令及其顺序是:a->b->c
执行package命令会按顺序执行compile,test命令后再执行package打包命令。
生命周期包含的阶段:一共三个阶段
    (1)clean lifecycle:清理
        pre-clean、clean、post-clearn
    (2) default lifecycle:默认(最重要最常见的命令)
        很多包括compile、test-compile、test、package、install、deploy等
    (3)site lifecycle:站点
        pre-site、site、post-site、site-deploy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值