Maven学习

1. 项目构建过程

构建过程的几个主要环节

  1. 清理:删除以前的编译结果,为重新编译做好准备。

  2. 编译:将Java源程序编译为字节码文件。

  3. 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。

  4. 报告:在每一次测试后以标准的格式记录和展示测试结果。

  5. 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应war包。

  6. 安装:在Maven环境下特指将jar包安装到本地仓库中。这样该项目就可以被其他的maven项目通过依赖的方式引入。

  7. 部署:将jar包部署到私服上。

Maven的两大核心功能(重点)

项目构建

对项目进行编译,测试,打包,部署等构建。

依赖管理

对jar包的统一管理,Maven提供中央仓库,私服,本地仓库解决jar包的依赖和相关依赖的下载。如下图所示:包括蓝、黄两个部分分别对应着依赖关系和 项目构建两大核心功能。

Maven的核心概念

什么是POM

POM(Project Object Model)项目对象模型,它是Maven的核心组件。它是Maven中的基本工作单元。它是一个xml文件,以pom.xml驻留在项目的根目录中。POM不仅包含有关项目的信息及Maven用于构建项目的各种配置的详细信息,还包含目标和插件。

什么是约定的目录结构

预先约定好的目录结构,必须要遵循的规范,所有的Maven项目都依照这个规范。主要的目的是将项目的源码文件,测试代码,资源文件完全分开,便于项目管理和扩展。

什么是坐标GAV

gav定位。使用三个标签来唯一定位jar资源。项目的唯一的名称,创建项目时定义gav名称,引用项目时使用gav名称。相当于项目的身份证号。


groupId: 组织名称,一般是公司域名的倒写 com.bjpowernode

artifactId:项目名称 springmvc_006_ssm

version: 版本编号 1.0-SNAPSHOT(开发时的临时版本号) 5.2.5.RELEASE(发布版本)


什么是仓库

存放jar包的位置 。Maven中所有的jar包都在仓库中。仓库分为本地仓库和远程仓库。

依赖的jar包它从哪儿获取呢?maven有仓库的概念。**在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。**Maven 核心程序仅仅定义了自动化构建项目的生命周期,但具体的构建工作是由特定的构件完成的。而且为了提高构建的效率和构件复用,maven把所有的构件统一存储在某一个位置,这个位置就叫做仓库。

本地仓库:路径中不要有中文;

本地仓库

本地仓库,存在于当前电脑上,默认存放在~.m2\repository中,为本机上所有的Maven工程服务。你也可以通过Maven的配置文件Maven_home/conf/settings.xml中修改本地仓库所在的目录。~ 是用户的主目录,windows系统中是 c:/user/登录系统的用户名

存放在本机上的某个磁盘的位置(一定是没有中文的路径). D:\repository

远程仓库

远程仓库,分为为全世界范围内的开发人员提供服务的中央仓库、为全世界范围内某些特定的用户提供服务的中央仓库镜像、为本公司提供服务自己架设的私服。

中央仓库是maven默认的远程仓库,其地址是:http://repo.maven.apache.org/maven2/,中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载得到。

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。还可以把一些无法从外部仓库下载到的构件上传到私服上。

程序员常用的一个仓库: http://mvnrepository.com/

什么是依赖

添加jar包

一个Maven 项目正常运行需要其它项目的支持,Maven 会根据坐标自动到本地仓库中进行查找。对于程序员自己的 Maven 项目需要进行安装,才能保存到仓库中。不用maven 的时候所有的 jar 都不是你的,需要去各个地方下载拷贝,用了 maven 所有的 jar 包都是你的,想用谁,叫谁的名字就行。maven 帮你下载。

除了管理当前要使用的jar包,并且同时管理与其有依赖关系的jar包,自动去下载,并添加到当前的仓库,并给项目添加引用。是通过<dependencies>大标签中的子标签<dependency>,使用gav添加依赖。

什么是生命周期

构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个阶段,都是从这个生命周期的最初阶段开始的。

对于程序员而言,无论要进行哪个阶段的构建,直接执行相应的命令即可,无需担心它前边阶段是否构建,Maven 都会自动构建。这也就是 Maven 这种自动化构建工具给我们带来的好处。

使用idea后,生命周期要调用的命令被集成化一些按钮,只需要双击即可调用相应的插件来运行。

生命周期对应的Maven命令(了解):

  1. mvn clean 清理(删除原来编译和测试的目录,即 target 目录,但是已经 install 到仓库里的包不会删除)

  2. mvn compile 编译主程序(在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件)

  3. mvn test-compile 编译测试程序(在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件)

  4. mvn test 测试(生成一个目录surefire-reports,保存测试结果)

  5. mvn package 打包主程序 (首先执行编译、编译测试、测试、并且按照 pom.xml 配置把主程序打包生成 jar 包或者 war 包)

  6. mvn install 安装主程序(会把本工程打包,并且按照本工程的坐标保存到本地仓库中)

  7. mvn deploy 部署主程序(部署到私服仓库中)。

什么是插件

Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的。进一步说,每个任务对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如maven- compiler-plugin的compile目标用来编译位于src/main/java/目录下的主源码,testCompile目标用来编译位于src/test/java/目录下的测试源码。

Maven支持极简化的插件添加.使用<plugins>大标签中添加<plugin>子标签引用插件.

XML 复制代码
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>17</source>
      <target>17</target>
      <encoding>UTF-8</encoding>
    </configuration>
  </plugin>
</plugins>

基于Maven开发JavaSE的项目

java 复制代码
public class Hello {
    //加法运算
    public int sum(int num1,int num2){
       return num1 + num2;
    }
    //乘法运算
    public int mul(int num1,int num2){
        return num1 * num2;
    }
}

Test

java 复制代码
public class MyTest {
    /**
     * 测试功能由测试方法来实现
     * 测试方法的规范
     * 1)访问权限是public
     * 2)方法没有返回值void
     * 3)方法名称自 定义,推荐以test开头
     * 4)方法没有参数
     * 5)使用@Test注解声明是测试方法
     */
    @Test
    public void testSum(){
        Hello  hello = new Hello();
        System.out.println(hello.sum(3,6));
    }
    @Test
    public void testMul(){
        Hello  hello = new Hello();
        System.out.println(hello.mul(3,6));
    }
}

基于Maven开发JavaWeb的项目

java 复制代码
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("服务器被访问到了..........");
		req.getRequestDispatcher("/main.jsp").forward(req, resp);
	}
}

index.jsp

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
  <br><br>
  <a href="/demo">访问服务器</a>
  </body>
</html>

main.jsp

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>main........................</h2>
</body>
</html>

JSP:

1.直接写HTML代码,就像在普通HTML文件中一样。

2.嵌入Java代码,使用<% %>脚本片段,或者使用JSP标签(如<jsp:useBean>)和EL表达式(${})来更优雅地集成Java代码。

3.使用JSP指令(如<%@ page %>)设置页面属性,比如 contentType 和 language。

4.使用JSP声明(<%! %>)声明成员变量和方法。

5.使用JSP表达式(<%= %>)将Java表达式的值输出到HTML中。

Maven的依赖管理

在JAVA开发中,项目的依赖管理是一项重要任务。通过合理管理项目的依赖关系,我们可以有效的管理第三方库,模块的引用及版本控制。

什么是依赖范围

Maven的依赖构件包含一个依赖范围的属性。这个属性描述的是三套classpath的控制,即编译、测试、运行。这说白了就是添加的jar包起作用的范围。 maven提供了以下几种依赖范围:compile,test,provided.runtime,system。分别介绍如下:

1. compile

编译依赖范围,如果没有指定,默认使用该依赖范围,对于 编译、测试、运行3种classpath都有效。

2. test

测试依赖范围,使用此依赖范围的maven依赖,只对 编译、测试、运行测试的classpath有效,在编译主代码、运行项目时无法使用此类依赖。比如junit,它只有在编译测试代码及运行测试的时候才需要。

3. provided

已提供依赖范围。表示项目的运行环境中已经提供了所需要的构件,对于此依赖范围的maven依赖,对于 编译源码、编译测试、运行测试中classpath有效,但在运行时无效。比如上面说到的servlet-api,这个在编译和测试的时候需要用到,但是在运行的时候,web容器已经提供了,就不需要maven帮忙引入了。

4. runtime

运行时依赖范围,使用此依赖范围的maven依赖,对于 测试和运行 项目的classpath有效,但在编译时无效,比如jdbc驱动实现,项目代码编译的时候只需要提供JDK提供的JDBC接口,运行的时候才需要具体的jdbc驱动实现。

5. system

系统依赖范围,该依赖与3中classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显示第指定依赖文件的路径。这种依赖直接依赖于本地路径中的构件(jar包),可能每个开发者机器中构件的路径不一致,所以如果使用这种写法,机器中可能没有问题,别人的机器中就会有问题,所以建议谨慎使用。

依赖传递

依赖具有传递性。 Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖,这在一定程序上简化 了POM 的配置。

假设项目A依赖项目B,项目B依赖项目C,则A----->直接依赖B,B----->直接依赖C,A----->间接依赖C。直接依赖和间接依赖是一个相对的概念。直接在项目中配置的依赖称为直接依赖,通过添加依赖关联进来的依赖称为间接依赖。1是项目的直接依赖,2是1的直接依赖,2是项目的间接依赖,以此类推。如图

依赖范围对依赖传递的影响

B 是 A 的直接依赖,C 是 A 的间接依赖,根据 Maven 的依赖传递机制,间接依赖 C 会以传递性依赖的形式引入到 A 中,但这种引入并不是无条件的,它会受到依赖范围的影响。

行指的是直接依赖,列指的是间接依赖(表格里的内容就是laoda看到时的状态)

| | compile | test | provided | runtime |
| compile | compile | 0 | 0 | runtime |
| test | test | 0 | 0 | test |
| provided | provided | 0 | 0 | provided |

runtime runtime 0 0 runtime
  1. 当间接依赖的范围是 compile 时,与直接依赖的范围一致;

  2. 当间接依赖的范围是 test 或 provided 时,传递性依赖不会被传递;因为打包之后本来就不存在子依赖中,所以更不会出现在父依赖中;

  3. 当间接依赖的范围是 runtime 时,传递性依赖的范围与直接依赖的范围一致,但 compile 例外,此时传递性依赖的范围为 runtime。


XML 复制代码
<groupId>com.hnlg</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 父工程的打包方式,此工程不能运行,只是用来规范和定义的   -->
<packaging>pom</packaging>
<modules>
    <module>maven_son</module>
</modules>


<!-- dependencyManagement标签只是用来定义,并没有真正的添加依赖   -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程依赖

XML 复制代码
<parent>
    <groupId>com.hnlg</groupId>
    <artifactId>maven_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

<artifactId>maven_son</artifactId>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
相关推荐
znhy@1232 小时前
十一、Maven web项目的构建
java·maven
paopao_wu2 小时前
Spring AI 从入门到实战-目录
java·人工智能·spring
Hello.Reader2 小时前
用 Maven 配置 Flink 从初始化到可部署的完整实践
java·flink·maven
海梨花3 小时前
【从零开始学习RabbitMQ】
分布式·学习·rabbitmq
java_logo3 小时前
使用 Docker 部署 Nginx 教程
java·spring cloud·eureka
小蒜学长3 小时前
springboot基于BS的小区家政服务预约平台(代码+数据库+LW)
java·数据库·spring boot·后端
952364 小时前
数据结构—单链表
c语言·数据结构·学习
我命由我123454 小时前
Git 暂存文件警告信息:warning: LF will be replaced by CRLF in XXX.java.
java·linux·笔记·git·后端·学习·java-ee
小胖同学~4 小时前
JVM内存模型剖析
java·jvm