Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。
一个 Maven 工程有约定的目录结构,约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环,就拿自动编译来说,Maven 必须 能找到 Java 源文件,下一步才能编译,而编译之后也必须有一个准确的位置保持编译得到的字节码文件。 我们在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式
在没有maven前:
在有了maven后:
不同IDE之间的项目结构不同会导致IDE之间不通用,而maven就解决了这个问题
每一个项目都会经过,编译,测试,打包,发布,利用简单的命令就能完成一些大型项目
管理你项目所依赖的第三方资源(因为如果项目较大,那jar包也会很多,得去一个一个的去网上找资源下载jar包,而maven就解决了这个问题,给一个坐标的配置就能轻松导入jar包)
1.项目对象模型:每个jar包的唯一标识
2.仓库:maven去哪调用了这些jar包呢?是去仓库找到了jar包
因为国外的中央仓库访问速度比较慢,还有一些jar包有版权找不到,所以国内或企业就建立了私服远程仓库
首页:Maven – Welcome to Apache Maven
下载页面:Maven – Download Apache Maven
本地仓库默认值:用户家目录/.m2/repository。由于本地仓库的默认位置是在用户的家目录下,而家目录往往是在 C 盘,也就是系统盘。将来 Maven 仓库中 jar 包越来越多,仓库体积越来越大,可能会拖慢 C 盘运行速度,影响系统性能。所以建议将 Maven 的本地仓库放在其他盘符下。配置方式如下:
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>D:\software\maven-repository</localRepository>
本地仓库这个目录,我们手动创建一个空的目录即可。
记住:一定要把 localRepository 标签从注释中拿出来。
注意:本地仓库本身也需要使用一个非中文、没有空格的目录。
Maven 下载 jar 包默认访问境外的中央仓库,而国外网站速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让 Maven 下载 jar 包的时候速度更快。配置的方式是:
<!-- <mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror> -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
如果按照默认配置运行,Java 工程使用的默认 JDK 版本是 1.5,而我们熟悉和常用的是 JDK 1.8 版本。修改配置的方式是:将 profile
标签整个复制到 settings.xml 文件的 profiles
标签内。
<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>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
数学中的坐标使用 x、y、z 三个『向量』作为空间的坐标系,可以在『空间』中唯一的定位到一个『点』。
Maven中的坐标使用三个『向量』在『Maven的仓库』中唯一的定位到一个『jar』包。
例如:groupId:com.javatv.maven
例如:artifactId:auth
例如:version:1.0.0
提示:坐标和仓库中 jar 包的存储路径之间的对应关系,如下
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
上面坐标对应的 jar 包在 Maven 本地仓库中的位置:
Maven本地仓库根目录\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar
**POM:Project Object Model,项目对象模型。**和 POM 类似的是:DOM(Document Object Model),文档对象模型。它们都是模型化思想的具体体现。POM 表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。
POM 理念集中体现在 Maven 工程根目录下 pom.xml 这个配置文件中。所以这个 pom.xml 配置文件就是 Maven 工程的核心配置文件。其实学习 Maven 就是学这个文件怎么配置,各个配置有什么用。
<!-- 当前Maven工程的坐标 -->
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<!-- 当前Maven工程的打包方式,可选值有下面三种: -->
<!-- jar:表示这个工程是一个Java工程 -->
<!-- war:表示这个工程是一个Web工程 -->
<!-- pom:表示这个工程是“管理其他工程”的工程 -->
<packaging>jar</packaging>
<properties>
<!-- 工程构建过程中读取源码时使用的字符集 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 当前工程所依赖的jar包 -->
<dependencies>
<!-- 使用dependency配置一个具体的依赖 -->
<dependency>
<!-- 在dependency标签内使用具体的坐标依赖我们需要的一个jar包 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- scope标签配置依赖的范围 -->
<scope>test</scope>
</dependency>
</dependencies>
目的:项目的扩展性变强了,方便其他项目引用相同的功能。
具体来说:
解耦,模块化和复用性: 将系统分解为模块可以提高代码的模块化程度,每个模块专注于特定的功能或业务逻辑。这种模块化的设计有利于提高代码的复用性,可以更方便地在不同的系统中重用模块。
简化开发和维护: 分模块开发可以让团队成员专注于各自模块的开发工作,减少了开发过程中的复杂性。此外,当系统需要维护或进行扩展时,可以更容易地定位和修改特定模块,而不影响其他部分的代码。
团队协作和并行开发: 通过划分模块,不同的开发人员可以独立负责不同的模块,从而实现并行开发。这有助于提高团队的协作效率,同时也可以缩短软件开发周期。
提高系统的可维护性和可扩展性: 由于各个模块之间的相对独立性,当需要对系统进行扩展或修改时,可以更容易地理解和管理各个模块,降低了对整个系统的影响。
降低风险和便于测试: 各个模块相对独立,对于系统进行单元测试、集成测试和功能测试时可以更加简便,同时在部署和故障排查时可以更容易地定位问题范围。
首先明白模块之间怎么联系:对于从中央仓库或私服仓库导入的插件或jar先是通过从中央仓库或私服下载到本地仓库中,再导入到该项目,所以多模块开发就是将相应的jar包导入本地仓库供其他模块使用,其groupId便是本地仓库的文件目录,而maven就提供了直接打jar包并放入本地仓库的插件
mvn install
注意事项:
上面说到我们使用 Maven 最主要的就是使用它的依赖管理功能,引入依赖存在一个范围,maven的依赖范围包括: compile,provide,runtime,test,system。
依赖范围 | 编译 | 测试 | 运行时 | 是否会被打入jar包 |
---|---|---|---|---|
compile | √ | √ | √ | √ |
provided | √ | √ | × | × |
runtime | × | √ | √ | √ |
test | × | √ | × | × |
system | √ | √ | × | √ |
而在实际开发中,我们常用的就是 compile
、test
、provided
。
A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?
再以上的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
依赖冲突的优先级
A依赖B,B依赖C,B不想被A依赖可以选择false隐藏
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven_B_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递性-->
<optional>false</optional>
</dependency>
A依赖B,B依赖C,A不想依赖B可以选择在A中排除B
excludes
标签配置依赖的排除:<dependency>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除依赖是隐藏当前资源对应的依赖关系-->
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
什么叫聚合?
聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合,就是如果B依赖C但是C改了其中影响B的量,那么错误难以排除,但是聚合就可以统一对模块进行构建,编译,等操作,等一个jar改变时直接提醒报错。
聚合工程:通常是一个不具有业务功能的==”空“==工程(有且仅有一个pom文件)
作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
<packaging>pom</packaging>
注意事项:
<modules>
<module>../maven_ssm</module>
<module>../maven_pojo</module>
<module>../maven_dao</module>
</modules>
注意事项:
用一个空模块来进行聚合!
Maven工程之间,A 工程继承 B 工程
本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。
通常是一个不具有业务功能的==”空“==工程(有且仅有一个pom文件)与继承一样
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
需求一:这三个项目都需要spring包
需求二:前两个需要test
它背后的需求是:
<packaging>pom</packaging>
注意事项:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
……
</dependencies>
此为可选依赖当继承此工程时,如果加上该名jar包而不写版本便是该工程版本,完成需求二
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
……
</dependencies>
</dependencyManagement>
完成需求一
<!--定义该工程的父工程-->
<parent>
<groupId>com.itheima</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--填写父工程的pom文件,根据实际情况填写,加速找到-->
<relativePath>../maven_parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<!--不需要加版本,因为是继承的工程-->
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
注意事项:
聚合和继承的作用?
属性具体来说就是一个变量,定义属性有什么好处?通过改变一个来统一改变简化开发
可以通过控制父类继承再控制全部
<!--定义自定义属性-->
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--定义自定义属性-->
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<junit.version>4.12</junit.version>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</properties>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
就是让此resources下的文件去识别pom文件中的变量能够使用${}
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
自上而下的优先级
可以通过上述命令去找到变量都有啥。
项目开发的版本可以分为哪几种?
<!--定义多环境-->
<profile
<!--定义具体的环境:生产环境-->
<profile>
<!--定义环境对应的唯一名称-->
<id>env_dep</id>
<!--定义环境中专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</properties>
<!--设置默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--定义具体的环境:开发环境-->
<profile>
<id>env_pro</id>
……
</profile>
</profiles>
【命令】:
mvn 指令 –P 环境定义id
【范例】:
mvn install –P pro_env
因为在构建过程中你只想测试某个功能即使你知道有些功能没有完善会报错,因此跳过测试这些错误直接打jar包就是跳过测试
注意事项:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests>
<!--设置跳过测试-->
<includes>
<!--包含指定的测试用例-->
<include>**/User*Test.java</include>
</includes>
<excludes>
<!--排除指定的测试用例-->
<exclude>**/User*TestCase.java</exclude>
</excludes>
</configuration>
</plugin>
团队开发现状分析
私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题
Nexus
启动服务器(命令行启动)
访问服务器(默认端口:8081)
修改基础配置信息
修改服务器运行配置信息
宿主仓库:是用于存储和管理开发团队自主研发的软件包、库和资源的地方。它提供了版本控制、权限管理和发布功能,使团队成员可以上传、下载和管理这些软件包和资源。宿主仓库可以包含自己开发的代码、库和工具,以及第三方的软件包,方便团队内部统一管理和使用。
代理仓库:充当了中间缓存的角色,用于在使用外部或公共的远程仓库时加快访问速度。代理仓库会缓存从远程仓库下载的软件包,以便下次请求时可以直接从缓存中获取,从而提高软件包下载的效率。这样可以减少对远程仓库的依赖,加快构建过程,并提供离线访问的能力
仓库组是一个逻辑组合,将多个宿主仓库和代理仓库组合成一个统一的仓库。仓库组可以由多个宿主仓库和代理仓库组成,并提供单一的访问点。这样,开发人员可以从仓库组中获取所需的软件包和资源,而无需关心具体的底层仓库。仓库组能够简化依赖管理,并提供对多个仓库的透明访问。
往私服上传资源是否需要身份认证?在哪里设置认证信息?
【第一步】在maven的settings.xml中<mirrors>标签中配置,此时就需要注释掉aliyun的配置。
<mirror>
<id>nexus-heima</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
【第二步】在nexus中设置允许匿名下载,如果不允许将不会从私服中下载依赖
如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。
【第一步】配置本地仓库访问私服的权限(在maven的settings.xml的servers标签中配置)
<server>
<!--id任意,多个server的id不重复就行,后面会用到-->
<id>heima-nexus</id>
<username>admin</username>
<password>123456</password><!--填写自己nexus设定的登录秘密-->
</server>
【第一步】配置当前项目访问私服上传资源的保存位置(项目的pom.xml文件中配置)
<distributionManagement>
<repository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>heima-nexus</id>
<!--如果jar的版本是release版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/heima-releases/</url>
</repository>
<snapshotRepository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>heima-nexus</id>
<!--如果jar的版本是snapshot版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/heima-snapshots/</url>
</snapshotRepository>
</distributionManagement>
注意:要和maven的settings.xml中server中定义的<id>heima-nexus</id>对应
【第三步】发布资源到私服命令
mvn deploy
heima-nexus
admin
123456
【第一步】配置当前项目访问私服上传资源的保存位置(项目的pom.xml文件中配置)
```xml
<distributionManagement>
<repository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>heima-nexus</id>
<!--如果jar的版本是release版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/heima-releases/</url>
</repository>
<snapshotRepository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>heima-nexus</id>
<!--如果jar的版本是snapshot版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/heima-snapshots/</url>
</snapshotRepository>
</distributionManagement>
注意:要和maven的settings.xml中server中定义的<id>heima-nexus</id>对应
【第三步】发布资源到私服命令
mvn deploy