齐爷学Maven
一、Maven简介
Maven的应用场景:依赖导入、项目构建、依赖分享
1.Maven介绍
Maven是一个一键式的自动化的依赖管理工具,我们可以通过Maven来方便的导入依赖,可以自动的帮助我们下载jar包,可以同时进行多个项目的编译运行。Maven提供了自动化的测试插件,帮助我们进行项目测试功能的运行。资源文件和配置文件的整合,来打包和部署也可以通过Maven实现。
只需在Maven中配置,就能实现jar包的导入,无需手动将jar包放入项目对应的目录中。
jar包互相之间有依赖关系,关系复杂,导入很麻烦,而在Maven中我们只需要导入核心依赖即可。
Maven是一个项目构建工具,脱离了IDEA时如果我们仍需构建(比如在Linux操作系统下的服务器中),这时我们就需要Maven了。
Maven的官方解析文档:https://maven.apache.org/what-is-maven.html
Maven是为java项目管理构建、依赖管理的工具/软件,使用Maven可以自动化构建、测试、打包和发布项目,提高了开发效率和质量。
2.项目构建过程
1.清理:将上次编译的结果删除,为下一次编译做准备。
2.编译:将.java的文件编译生成.class字节码文件。(IDEA底层就是通过Maven实现的编译功能)
3.测试:针对项目中的关键点进行测试,确保项目在迭代开发的过程中关键点的正确性。
4.报告:在每一次测试后以标准的格式记录和展示测试结果。
5.打包:将项目生成jar包或war包。
6.安装:将jar包安装到本地仓库。
7.部署:将jar包部署到私服上。
3.Maven的两大核心功能
1.项目构建:对项目进行编译、测试、打包、部署等功能。
2.依赖管理:对jar包的统一管理,Maven提供远程/中央仓库、本地仓库、私服解决jar包的依赖和相关依赖的下载。
4.Maven的核心概念
1.POM
POM(Project Object Model) 项目对象模型,它是Maven的核心组件,是以pom.xml文件的形式存在,其中包含了项目的相关属性以及引用的插件、添加的依赖等。
2.约定的目录结构
Maven有一个约定的目录结构,我们必须遵循这种结构。
将Java源码和测试代码拆分,便于项目的管理和拓展。
例子:
springmvc_01
src
main //所有的java源码文件和相关的配置
java //所有的java源码文件
com.qiye.controller
.service
.mapper
.pojo
resources //所有的配置文件
SqlMapConfig.xml
applicationContext_mapper.xml
applicationContext_service.xml
springmvc.xml
jdbc.properties
test //所有的测试相关的代码和配置文件
java //所有的测试代码
resources //所有的测试相关的配置文件
pom.xml
3.坐标GAV
坐标就是资源的唯一定位。
创建项目时使用坐标拟定一个名称,访问资源时通过坐标找到资源。
G:groupId 组织名称,一般是公司名称的倒写 例:com.eyiq
A:artifactId 项目名称,例:spring_mvc001
V:version 版本编号,例:5.6.8 8.0.13等
表现在仓库的时候,GAV是一级一级的目录。
4.仓库
存放jar包的位置,Maven中所有的jar包都放到仓库中,仓库分为本地仓库和远程仓库。
本机存储jar包的位置称为本地仓库,远程存储jar包的位置称为远程仓库。
本地仓库:必须在没有中文的路径下。
远程仓库:通过局域网(称为私服)或互联网(为Maven中央仓库或Maven中央仓库的镜像)访问的仓库地址。
程序员常用的一个仓库(超全的仓库):http://mvnrepository.com/
5.依赖
依赖就是添加的jar包,所有的资源是以GAV进行定义的,也是通过GAV来添加引用,在<dependencies>大标签中,通过子标签<dependency>,通过GAV进行引用。
6.生命周期
对应项目构建的过程,底层是Maven命令的调用(插件)。
7.插件
Maven本质上是一个插件的框架,插件就是集成化的功能。
通过<plugins>大标签,再通过<plugin>子标签进行极简化的添加插件。
常见的插件:Tomcat插件、编译插件、MyBatis的逆向工程插件......
二、Maven的使用
1.Maven安装
Maven的官方下载地址:https://maven.apache.org/docs/history.html
版本选择:3.8.8
Maven的结构 bin 核心命令 boot 核心jar包 conf Maven工具自己的配置文件 lib Maven的依赖
要配置环境变量:保证有JAVA_HOME配置了jdk,然后配置MAVEN_HOME,路径为bin的上级目录,最后配置Path,添加%MAVEN_HOME%/bin 和 %JAVA_HOME%/bin
在cmd执行如下的命令,查看是否成功配置Maven的环境变量。
mvn -v
我们还要配置Maven工具参数
在 conf 中的 settings.xml 下配置
1.配置本地仓库:将第53行注释中的内容拿出来放到第55行,将本地仓库的路径放进去。
2.配置远程仓库:在mirrors中配置(中央仓库地址在国外,而且用的人多,所以我们使用阿里的镜像)
id为当前镜像的唯一标识名称,name为自定义命名的访问名称,url为阿里的远程镜像地址,
mirrorOf中的central意思为取代了中央镜像。
<!-- 配置阿里远程仓库 -->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
3.配置JDK属性
放到profiles中,下面代码是jdk17的配置(你使用的jdk是什么版本就写多少)
<profile>
<id>jdk17</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>17</jdk>
</activation>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
</properties>
</profile>
2.Maven在cmd下的使用
一定要联网
在项目目录的cmd下调用该命令打包Maven项目
mvn package
3.Maven在idea中的配置
为IDEA配置Maven工具
运行程序下:VM选项配置为
-DarchetypeCatalog=internal
选中本地仓库,点更新
为新建的项目配置Maven工具
在新项目设置中,做和IDEA配置相同的操作,只是少了刷新本地仓库的操作。
4.基于Maven创建javaSE项目
创建空项目 -> 配置jdk -> 新建模块 -> 生成代码
test测试目录中的文件不能直接叫test
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>com.eyiq</groupId>
<artifactId>maven_01_javase</artifactId>
<version>1.0-SNAPSHOT</version>
<!--默认打jar包-->
<!--<packaging>jar</packaging>-->
<!-- 添加依赖 -->
<dependencies>
<!-- 添加junit依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
<scope>test</scope>
</dependency>
<!-- 添加Mybatis框架的依赖-->
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Hello
public class Hello {
public int sum(int num1, int num2) {
return num1 + num2;
}
}
HelloTest
public class HelloTest {
// 所有测试功能的功能都由测试方法实现
//测试方法的规范:1.访问权限是public 2.方法没有返回值 3.方法名称可以自定义,推荐以test结尾
//4.方法没有参数 5.要以@Test注解声明是一个测试方法
@Test
public void testSum(){
Hello hello = new Hello();
System.out.println(hello.sum(2,6));
}
}
5.基于Maven的javaWeb项目
新建模块 -> 选择Maven Archetype -> Archetype选择maven-archetype-webapp -> 创建 -> 补齐缺失的目录 -> 在web-app下创建index.jsp和main.jsp(删除原先的index.jsp) ->配置Tomcat,工件要选带exploded的,要更新类和资源 ->更改web.xml的版本(在项目结构下)
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.eyiq</groupId>
<artifactId>maven_02_javaweb</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
DemoServlet
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {
/**
* 客户端:<a herf="/demo">访问服务器</a>
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("服务器被访问了");
//请求跳转
req.getRequestDispatcher("/main.jsp").forward(req,resp);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
</web-app>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Index</title>
</head>
<body>
<br><br><br>
<a href="/demo">访问服务器</a>
</body>
</html>
main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Main</title>
</head>
<body>
<br><br><br>
<h2>main.......</h2>
</body>
</html>
6.导入Maven项目
把到导入的项目放到我们的project中,此时并没有项目的标识,我们需要在项目结构中导入项目,导入到当前工作区,指定为Maven。
这样的目录样式代表成功导入了。
三、Maven的依赖管理
1.依赖范围
<scope>标签可以设置依赖的范围
1.compile 默认的值 在所有范围内生效
2.test 只在测试范围内有效
3.provided 提供依赖范围,一般提供在Servlet相关的依赖上。在主代码和测试代码中有效,在运行时无效。(web项目在Tomcat上运行,Tomcat中有需要的依赖,所以不需要我们自己导入的依赖)
4.runtime 运行时依赖范围 只对测试和运行有效,对编译无效。
5.system 系统依赖范围 完全指定本地磁盘上的依赖的路径来使用(少用),并非是Maven仓库中的依赖。
总结:
compile 编译、测试、运行都生效(spring-context)
test 测试生效(junit)
provided 编译、测试有效。(是别人的,例如servlet-api)
runtime 测试、运行有效。(jdbc驱动)
system 编译、测试有效。(非Maven仓库的本地jar包)
2.依赖传递
依赖的传递性
依赖具有传递性,如果A依赖于B,B依赖于C。那么A和B、B和C为直接依赖,A和C为间接依赖。
在Maven中添加直接依赖后,相关的间接依赖也会直接导入,这对于我们来说是很方便的。
依赖的范围对依赖的影响
A依赖于B,B依赖于C时:
下表,左为A对B的依赖范围,上为B对C的依赖范围,中间的结果为A对C的依赖范围。
compile | test | provided | runtime | |
compile | compile | 无 | 无 | runtime |
test | test | 无 | 无 | test |
provided | provided | 无 | 无 | provided |
runtime | runtime | 无 | 无 | runtime |
结论:
1.间接依赖是compile时,与直接依赖的范围一致。
2.间接依赖时test或provided时,传递性依赖不会被传递。
3.间接依赖是runtime时,与直接依赖的范围一致,除了compile是runtime。
3.依赖冲突及解决方案:
隐式的引入了多个不同版本的的相同依赖。
1.版本锁定
父工程中锁定版本。
父工程
<?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>com.eyiq</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- pom是父工程的打包方式,此工程不能运行,只是来进行规范和定义的-->
<packaging>pom</packaging>
<modules>
<module>maven_son</module>
</modules>
<!-- dependencyManagement标签只是用来定义,并没有真正的添加依赖 -->
<!-- (会导致子工程获得一些不需要的依赖)如果父工程不写dependencyManagement标签而直接写dependencies标签,子工程会继承这些依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
子工程
<?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>
<parent>
<groupId>com.eyiq</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的 G 和 V 与父工程保持一致-->
<artifactId>maven_son</artifactId>
<!-- 因为父工程中已经定义了junit的版本,在子工程中就无需指定版本了
子工程也可以指定自己选择的版本,类似于重写
-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
2.短路径优先
引入多个不同路径的不同版本的相同依赖时,优先选择路径最短的依赖。
验证短路径优先:
maven_02
<?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>com.eyiq</groupId>
<artifactId>maven_02</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 在maven_02中添加4.12版本的junit依赖 和 maven_03 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
maven_03
<?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>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 在maven_03中添加4.13.1版本的junit依赖-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
结果确实是遵循了短路径优先
3.声明优先
在路径长度相同的情况下,先声明的依赖优先。
验证 maven_01导入上方的maven_02和maven_03:
<?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>com.eyiq</groupId>
<artifactId>maven_01</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 在maven_01中添加maven_02和maven_03的依赖
此时先声明了maven_03,结果maven_03中的junit就生效了
-->
<dependencies>
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_02</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
明显发现,后声明的maven_02中的4.12版本的junit为灰色(未被使用)
4.特殊优先
由于不小心,同一个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>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 在maven_03中添加4.13.1版本和4.12版本的junit依赖-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
此时后设置的4.12版本会生效。
5.可选依赖
可以设置是否向外提供依赖。
验证:
maven_03
<?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>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<!-- 拒绝提供当前依赖 将optional设置为true-->
<optional>true</optional>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
maven_02
<?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>com.eyiq</groupId>
<artifactId>maven_02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
在maven_03的junit依赖的optional设置为true后,maven_02即使导入了maven_03,也无法使用maven_03中的junit依赖。
6.排除依赖
如果maven_02导入了maven_03,可以在maven_02中设置来排除maven_03中的依赖。
验证:
maven_02.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>com.eyiq</groupId>
<artifactId>maven_02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_03</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 排除依赖设置exclusions排除其他项目的junit依赖 -->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
此时maven_03的junit依赖不会出现。
4.刷新依赖的8种方式
idea中有时会刷新延迟,这时我们需要手动刷新,8种刷新方式总有一种会管用。
1.点击M刷新按钮。
2.点击Maven窗口的刷新按钮。
3.重构项目。
4.单独刷新某个pom文件。
5.物理刷新,把pom中的代码全部复制,删掉,再粘贴。
6.清空IDEA的缓存。
7.打开本地仓库,搜索last,全选删除,再点击Maven窗口的刷新(能解决只下载了一半的依赖)。
8.在7做完后还没有用时,File -> settings -> Buid、Execution、Deployment -> Maven -> Repositories -> update 再点击Maven窗口的刷新。
四、资源文件的指定(解决资源文件丢失问题)
一些不在resources的资源文件编译时会丢失,导致整个项目崩溃。
可以在pom.xml中配置如下代码
<build>
<resources>
<resource>
<!--指定java目录下的所有路径下的所有文件-->
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<!--指定resources目录下的所有路径下的所有文件-->
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
五、Maven继承和聚合
继承
作用:父工程定义规范,子工程继承,增加代码的可复用性和维护性。
可继承的元素:groupId,version,properties,dependencies,dependencyManagement,build
自定义属性的定义和使用方式
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 自定义属性-->
<qiye>66</qiye>
</properties>
<!-- 使用自定义属性-->
${qiye}
JavaSE的父子工程继承实现
父工程
<?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>com.eyiq</groupId>
<artifactId>maven_fu</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包的方式为pom就是父工程 -->
<packaging>pom</packaging>
<modules>
<module>maven_zi_javase</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 添加两个自定义属性-->
<spring-version>5.3.24</spring-version>
<mybatis-version>3.5.11</mybatis-version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 添加spring-context依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- 添加myBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 设置插件 -->
<build>
<pluginManagement>
<plugins>
<!--只定义Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8089</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
子工程
<?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>
<!-- parent显示了当前的父元素 -->
<parent>
<groupId>com.eyiq</groupId>
<artifactId>maven_fu</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 此处子工程继承了父工程的groupId和version 所以只显示了artifactId-->
<artifactId>maven_zi_javase</artifactId>
<!-- 此处继承了父工程的依赖,版本号被父工程统一管理了 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
JavaWeb父子工程继承实现
如果webapp没有蓝色的小点,则JavaWeb是构建失败的,这时我们要在项目结构中给其添加Web并修改两个路径为正确的路径(web-app下)。如果web版本过低,我们还需要将之前修改的那两个路径删除并重新创建web.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>com.eyiq</groupId>
<artifactId>maven_fu</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包的方式为pom就是父工程 -->
<packaging>pom</packaging>
<modules>
<module>maven_zi_javase</module>
<module>maven_javaweb</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 添加两个自定义属性-->
<spring-version>5.3.24</spring-version>
<mybatis-version>3.5.11</mybatis-version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 添加spring-context依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- 添加myBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis-version}</version>
</dependency>
<!-- 添加servlet依赖 一定要添加scope设置依赖范围为provided-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 设置插件 -->
<build>
<pluginManagement>
<plugins>
<!--只定义Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8089</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
子工程
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.eyiq</groupId>
<artifactId>maven_fu</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>maven_javaweb</artifactId>
<packaging>war</packaging>
<name>maven_javaweb Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 继承父工程的servlet依赖-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
</dependencies>
<!-- 引用tomcat插件-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- 指定端口号-->
<configuration>
<port>8888</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</build>
</project>
聚合
聚合就是整体的项目构建过程。
在父工程中可以进行整体子工程的清理或打包等操作,但是如果不是父子工程时,就需要聚合来集中进行项目的构建。
maven_aggregate的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>com.eyiq</groupId>
<artifactId>maven_aggregate</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 实现聚合功能-->
<!-- 添加打包方式pom-->
<packaging>pom</packaging>
<!-- 通过modules标签实现聚合,实现多个项目的集中构建-->
<modules>
<module>../maven_01</module>
<module>../maven_03</module>
<module>../maven_fu</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
六、Maven的私服
1.概述
私服:是一种特殊的远程仓库,架设在局域网内的仓库服务。
Nexus默认设置了三种类型的仓库:
1.hosted 宿主仓库: 部署自己的jar包到这个类型的仓库中,包括Releases(发行版本)和Snapshots(测试版本)。
2.proxy 代理仓库(central):代理远程的公共仓库,如Maven中央仓库。
3.group 仓库组(public):合并多个hosted/proxy仓库。
2.下载和安装Nexus
官网:https://help.sonatype.com/repomanager3/download
下载完毕后,在bin目录下打开cmd,执行以下命令,每次使用Nexus私服都要进行该操作
nexus /run nexus
安装成功后,窗口不要关闭
http://localhost:8081 即为Nexus私服对应的工作台网站
在ect下的properties配置文件中可以更改默认端口。
Log in登录:用户名为admin,密码在sonatype-work的nexus3的admin-password中。
登录后要选择Disable anonymous access 拒绝匿名登陆,保证私服的安全。
在admin可以更改密码。
3.使用Nexus私服
创建仓库
设置 -> Repositories ->创建release和snapshot两个版本Maven的仓库 -> 将仓库放到public仓库中
设置Nexus阿里仓库地址
设置 -> Repositories ->选择maven-central ->Remote storage ->路径改为http://maven.aliyun.com/nexus/content/groups/public/
配置Maven工具访问私服
在setting.xml的servers中设置用户名和密码。
删除之前设置的阿里镜像,设置为私服地址。
<mirror>
<id>qye-nexus</id>
<mirrorOf>central</mirrorOf>
<name>mynexus</name>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
配置一个新的本地仓库,如果我们发现新的本地仓库和私服的public中都有了依赖,那么就意味着配置成功了!
上传资源到私服及下载使用
在要上传的项目中的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>com.eyiq</groupId>
<artifactId>maven_nexus</artifactId>
<!-- 此处指定上传入哪个库,不写默认为发行库release,写了snapshot为内测库-->
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--为项目进行部署(上传到私服)参数配置,上传到哪个库,以什么用户名和密码上传 -->
<distributionManagement>
<!-- 上传到发布仓库 -->
<repository>
<id>qiye-nexus</id>
<url>http://localhost:8081/repository/qiye-release/</url>
</repository>
<!-- 上传到内测仓库 -->
<snapshotRepository>
<id>qiye-nexus</id>
<url>http://localhost:8081/repository/qiye-snapshot/</url>
</snapshotRepository>
</distributionManagement>
</project>
然后点击生命周期中的deploy部署,此时是进入了snapshot中。
把version中的snapshot删除,再次部署就是进入了release中。
可以在其他的项目中使用之前部署的项目
<!-- 添加maven_nexus 1.0项目引用-->
<dependency>
<groupId>com.eyiq</groupId>
<artifactId>maven_nexus</artifactId>
<version>1.0</version>
</dependency>