maven学习笔记

概念

Maven的产生的目的是为了解决项目中依赖的管理,以及为项目的构建指定了新的规范

相关的依赖都存放在Maven的中央仓库中,那么怎么才能快速的定位到相关资源的存放位置呢?所以关于maven的资源定位有以下几个需要注意的概念:

  1. groupId

    组织id,例如:com.apache..

  2. artifactId

    项目id,常见是项目的名称

  3. version

    项目的版本号,常见的:release(发布版)snapshot(开发版)

  4. packaging(非必须)

    打包方式

安装Maven

这里仅简单的介绍描述安装Maven的过程

  1. 下载:到apache maven的官网中下载相关的安装包(官网地址
  2. 配置:maven是免安装的,下载后只需要配置环境变量maven_home,注意配置依赖于Java_home
  3. 验证:在命令行界面执行mvn相关的命令即可

两个常用的maven相关的网址:

  • 官方下载地址:https://maven.apache.org/download.cgi
  • 查询相关依赖:https://mvnrepository.com/

中央仓库、私服、本地仓库

在这里插入图片描述

当项目需要依赖时,首先会在本地仓库寻找,其次会去远程仓库拉取

setting配置文件

  • 指定本地仓库存放的位置

    <!-- 在配置文件中寻找该配置 -->
    <localRepository>E:\apache-maven-3.8.4\repository</localRepository>
    
  • 设置替换中央仓库的镜像

    <!-- 设置aliyun的maven镜像 -->
    <mirror>
    	<id>nexus-aliyun</id>
    	<mirrorOf>*</mirrorOf>
    	<name>Nexus aliyun</name>
    	<url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
    
  • 指定私服

mvn常用命令行

  • 清除:clean

    清除编译后产生的文件

  • 编译:compile

    编译项目的相关文件

  • 测试:test

    执行单元测试

  • 打包:package

    生成相应的jar文件

  • 安装:install

    将项目打包,并生成到maven的本地仓库中

IDEA创建maven项目

创建Java项目

在这里插入图片描述

步骤

  1. 创建empty project
  2. 在empty project中添加module,并且module的类型选择maven即可,其中的目录结构如图上2所示
  3. 给文件夹指定相应的类型

创建Java web项目

创建的步骤与上一步相同,不同的是选择了maven下的webapp的模板进行创建,在webapp可以引用tomcat7 插件进行启动,否则也可以将war包放入本地tomcat容器中

相关配置如下:

<build>
    <plugins>
        <plugin>
            <!--指定了tomcat容器插件-->
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <uriEncoding>utf-8</uriEncoding>
                <port>80</port>
                <url>/</url>
            </configuration>
        </plugin>
    </plugins>
</build>

pom.xml的配置详解

对于单个项目的配置文件大致可以分为以下这些,针对多个项目,多个模块要一起管理的,则还会有其他的配置项

<?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">
    <!--maven pom的模型版本,不需要修改-->
    <modelVersion>4.0.0</modelVersion>

    <!--组织id-->
    <groupId>org.example</groupId>
    <!--项目id-->
    <artifactId>study_01</artifactId>
    <!--版本号-->
    <version>1.0-SNAPSHOT</version>
    <!--打包方式-->
    <packaging>pom</packaging>

    <!--项目所有依赖-->
    <dependencies>
        <!--具体的依赖项-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--添加插件,插件可以在idea右侧下使用,比如tomcat:run-->
    <build>
        <plugins>
            <!--具体插件的内容和相关配置-->
            <plugin>
                <!--指定了tomcat容器插件-->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <!--相关的配置项-->
                <configuration>
                    <port>80</port>
                    <url>/</url>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

生命周期与插件

该内容比较复杂,算是maven比较底层的原理了,mvn将生命周期分为三部分

  • clean:清理
  • default:构建
  • site:构建项目站点

其中default是最为核心也是最为复杂的内容,生命周期是一个抽象的概念,所有构建项目的步骤都是由插件构成的,比如常用的:clean、complia、test、package、install都属于插件中的一部分,其中还有很多的阶段。

参考博客

依赖管理

在这里插入图片描述

  • 依赖配置

    项目中需要使用的依赖,就可以通过在pom.xml中来进行配置,比如

    <dependencies>
        <!--具体的依赖项-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            ...
        </dependency>
        ...
    </dependencies>
    
  • 依赖传递

    1. 概念从名称就能知道,不同项目的依赖,比如上图中项目A引用了项目B,项目B引用的项目C就传递给了项目A,这也就分为两类

      • 直接传递:对于引用项目B的项目A来说,这就是直接传递

      • 间接传递:对于通过中间项目B传递了一次的项目C和项目A的关系来讲,这就是间接传递

    2. 当发生依赖的版本发生冲突,并且不使用下面的可选依赖和排除依赖时,整体来讲会根据就近原则选择依赖

  • 可选依赖(不透明)

    将项目B的某些和项目A发送冲突的依赖设置为true(即项目A看不到项目B的这样依赖项)

    <!--项目B的依赖log4j设置optional为true,此时项目A将看不到项目B的该依赖-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
        <optional>true</optional>
    </dependency>
    
  • 排除依赖(不需要)

    与上面的可选依赖的主动将自身的依赖设置为不可见不同,排除依赖是指引用的这一方项目A排除掉项目B的某些依赖

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>study_webapp</artifactId>
        <version>1.0-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

依赖范围(scope)

maven的依赖范围包括: compile(默认),provide,runtime,test,system。

  • compile:表示编译范围,指A在编译时依赖B,该范围为默认依赖范围。编译范围的依赖会用在编译,测试,运行,由于运行时需要,所以编译范围的依赖会被打包。
  • provide:provide依赖只有当jdk或者一个容器已提供该依赖之后才使用。provide依赖在编译和测试时需要,在运行时不需要。例如:servlet api被Tomcat容器提供了。
  • runtime:runtime依赖在运行和测试系统时需要,但在编译时不需要。例如:jdbc的驱动包。由于运行时需要,所以runtime范围的依赖会被打包。
  • test:test范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要。例如:Junit。由于运行时不需要,所以test范围依赖不会被打包。
  • system:system范围依赖与provide类似,但是必须显示的提供一个对于本地系统中jar文件的路径。一般不推荐使用。

在这里插入图片描述

思考及了解:

项目A引用项目B中的依赖,而该依赖设置了范围为test,那么项目A还能读取到该依赖吗?

仅作了解即可

后续为maven的进阶学习

分模块开发

即是将一个单体的服务拆分成若干个更小的模块,各个模块都是maven项目,说简单点就将一个大的maven项目拆分成更小的多个maven项目,这样做的意义契合现在的微服务思想,更小的模块各司其职,但是对于各模块的治理难度上升了,但是maven有很多的解决方法

聚合

创建一个项目模块用作统一构建各个模块,通过指定packagingpom指定项目为统一构建的项目,并且该不需要src目录,因为它只用做构建管理。创建其他子模块,可以与该项目同级,也可以放置在该项目里面

// 放置在同级
project
	->project_manager
		->pom.xml
	->project_module01
		->src
		->pom.xml
	->project_module02
		->src
		->pom.xml
// 放置在project_manager的目录下
project
	->project_manager
		->pom.xml
		->project_module01
			->src
			->pom.xml
        ->project_module02
            ->src
            ->pom.xml

构建管理的pom.xml说明

<?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>org.example</groupId>
    <artifactId>study_partent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--pom指定该项目统一构建管理-->
    <packaging>pom</packaging>

    <modules>
        <module>../study_01</module>
        <module>../study_webapp</module>
    </modules>
</project>

继承

在上面的聚合的基础上,进一步对各模块进行管理,在这里可以将其划分为父工程和子工程,父工程的作用是统一构建管理,以及规定子工程各依赖的版本号

  • 指定父工程

    子工程指定父工程,如下通过在子工程的pom.xml中添加parent标签,即可指定父工程,由于指定了父工程,所以子工程的groupIdversion也应该和父工程保持一致,即删除了子工程的groupIdversion

    <parent>
        <groupId>org.example</groupId>
        <artifactId>study_partent</artifactId>
        <version>1.0-SNAPSHOT</version>
        <!--指定父工程的pom.xml的相对位置-->
        <relativePath>../study_partent/pom.xml</relativePath>
    </parent>
    <!--maven pom的模型版本,不需要修改-->
    <modelVersion>4.0.0</modelVersion>
    <!--项目id-->
    <artifactId>study_01</artifactId>
    <!--打包方式-->
    <packaging>jar</packaging>
    
  • 规定版本号

    父工程通过<dependencyManagement><pluginManagement>分别管理子工程依赖和插件的相应版本。通过自定义属性和**占位符$**管理父工程下的版本依赖,子工程需要引用依赖时,如果父工程指定了版本号,那么子工程不需要再指定版本号(仅仅只是版本号)。

    ps:父工程尽可能多的指定相关的版本号规范,但不意味着子工程不需要显示添加依赖了,子工程需要使用时,也需要添加依赖,只是不再添加版本。

    <properties>
        <log4j.version>1.2.16</log4j.version>
        <tomcat7.plugin.version>2.2</tomcat7.plugin.version>
    </properties>
    
    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.version}</version>
                </dependency>
            </dependencies>
    </dependencyManagement>
    
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>${tomcat7.plugin.version}</version>
                    <configuration>
                        <port>80</port>
                        <url>/</url>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    

属性

maven的pom.xml有五种属性,使用的比较多的,也比较重要的是自定义属性,为统一管理版本号提供了方法

<properties>
    <log4j.version>1.2.16</log4j.version>
    <tomcat7.plugin.version>2.2</tomcat7.plugin.version>
</properties>

配置文件绑定pom.xml的自定义属性

产生的前提:

项目中有很多的配置文件,比如application.xml或者application.properties,这些配置文件通常都存放在resources文件夹下,当多个子模块都有配置文件时,那么该怎么去方便的管理这些配置文件里的内容呢?比如想要统一管理所有子模块的数据库连接地址,不可能手动到每个模块的配置文件中去修改。所以maven支持通过在pom.xml文件中设置自定义属性和使用<resource>指明资源路径的方式,来动态的管理配置文件中的变量。而配置文件使用两种方式来设置占位符

  • ${自定义属性名称}
  • @自定义属性名称@
...
<properties>
    <jdbc.username>hhh</jdbc.username>
</properties>
...
<build>
    <!--指定main下的相关资源-->
    <resources>
        <resource>
            <!--指定配置文件的路径-->
            <directory>${project.basedir}/src/main/resources</directory>
            <!--是否开启映射自定义属性到资源文件-->
            <filtering>true</filtering>
        </resource>
    </resources>

    <!--指定test下的相关资源-->
    <testResources>
        <testResource>
            <!--指定配置文件的路径-->
            <directory>${project.basedir}/src/test/resources</directory>
            <!--是否开启映射自定义属性到资源文件-->
            <filtering>true</filtering>
        </testResource>
    </testResources>
</build>

配置文件里的内容:

# 使用$或者@@都可以获取到pom.xml的自定义属性内容
jdbc.username=${jdbc.username}
jdbc.test=@jdbc.username@
jdbc.password=123456

其中使用到了<resource>标签,这个标签放置在<build>下,是很重要的标签,能添加一些资源或者排除一些资源。等待后续更加深入的学习。

多环境配置

在实际的项目开发中肯定包含了很多不同的环境,比如开发环境、测试环境、生产环境。所以配置也应该有多套不同的配置。maven提供了不同的配置<profiles>,其中自定义标签可以在构建项目时进行勾选,maven的不同选择,会让配置文件读取的自定义属性不一样。再搭配springboot里的profile能配置多个配置文件,就能控制更多的配置文件了

<profiles>
    <profile>
        <id>dev</id><!-- 开发环境 -->
        <properties>
            <profileActive>dev</profileActive>
        </properties>
    </profile>
    <profile>
        <id>test</id><!-- 测试环境 -->
        <properties>
            <profileActive>test</profileActive>
        </properties>
    </profile>
    <profile>
        <id>pro</id><!-- 生产环境 -->
        <properties>
            <profileActive>pro</profileActive>
        </properties>
    </profile>
</profiles>

上传到远程仓库(私服)

公司内部开发会搭建相应的私服,用以存放内部开发的一些包,同时也方便其他开发人员的下载。私服上的仓库可以分为以下几类

  • 代理仓库:私服代理从其他的公共仓库中获取志愿,例如代理从中央仓库中获取资源
  • 宿主仓库:用户在私服上创建的仓库,用户将一些内部使用的资源上传到这里面,供公共使用
  • 仓库组:将多个仓库归类到一个组,这样在获取资源时,可以指定获取这个组内的所有 资源,是一个方便管理的抽象概念

相关配置的方法可以参考博客,配置好后使用depoly将生成的包发布到私服中

参考博客

遗留问题或待深入理解

  1. 将所有子模块的配置文件抽取成一个公共的config组件,各个application.yml使用占位符读取公共配置组件里的内容。目前是可行,但是创建的maven子模块读取到config公共组件的配置还有点问题,感觉像是与springboot的application.yml和application-dev.yml关系有关。待后续研究吧。
  2. mvn的生命周期和插件
  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值