Maven教程--下(包括手动实现)

Maven教程–下(包括手动实现)

前言

注意本篇是需要一定的maven基础的 如果没有请移步Maven教程–上

手动创建Maven 项目- 理解Maven 底层机制

需求说明/图解

用手工的方式,创建maven 项目, 深刻理解Maven 工作机制

完成功能-说明

  1. 编写一个类, 有一个方法sum,可以返回两个数的和
  2. 编写测试类TestSum, 可以测试sum 是否正确.
  3. 使用指令完成Maven 的编译(complile)、测试(test)、打包(package)、安装(install)、清理(clean)等操作

手写方式

完成代码编写

  1. 先根据maven 项目的结构要求,在d 盘: 创建项目结构(如图)

Maven教程--下(包括手动实现)_第1张图片

  1. 创建\Hello.java ,说明: 这个文件可以手写, 也可以从快速入门项目拷贝一份.
public class Hello {
    public String sum(int n1, int n2) {
        System.out.println("sum= " + (n1 + n2));
        return "sum= " + (n1 + n2);
    }
}
  1. 创建HelloTest.java,说明: 这个文件可以手写, 也可以从快速入门项目拷贝一份, 同时注意这个文件是在src\test… 下的…

public class HelloTest {

@Test
public void testSum() {

    Hello hello = new Hello();
    String res = hello.sum(1, 9);

    //使用断言
    /**
     * 1.Assert 是一个断言类,(就是判断实际返回的值和期望值是否相同)
     * 2.如果res 和 "sum=10" 是相同的,则通过断言
     * 3.如果res 和 "sum=10" 是不相同的,则给出提示
     *
     */
    Assert.assertEquals("sum=10", res);
}
  1. 创建pom.xml, 从快速入门项目拷贝一份即可. 放在和src 同级目录即可, 提示:使用记事本来保存, 保证该文件的编码是utf-8
    
    <modelVersion>4.0.0modelVersion>

    
    <groupId>com.wedugroupId>
    <artifactId>java-project-mavenartifactId>
    <version>1.0-SNAPSHOTversion>
    
    <dependencies>
        <dependency>
            
            <groupId>junitgroupId>
            
            <artifactId>junitartifactId>
            
            <version>4.12version>
        dependency>

Maven教程--下(包括手动实现)_第2张图片

完成编译

  1. 执行如下指令,完成maven 项目的编译,会得到源代码对应的class 文件(如图)

Maven教程--下(包括手动实现)_第3张图片

  1. 编程成功,会自动创建target 目录,并生成对应的.class 文件(如图)

Maven教程--下(包括手动实现)_第4张图片

  1. 细节说明: 第一次速度慢,需要下载相关jar,后面就快了.

完成测试

  1. 执行如下指令,完成maven 项目的测试,(如图)

  1. 测试指令执行完毕,会生成Test 源文件的class , 还会输出测试结果.

Maven教程--下(包括手动实现)_第5张图片

Maven教程--下(包括手动实现)_第6张图片

  1. 细节说明: 第一次速度慢,需要完成一些初始化工作,后面就快了.

完成打包

  1. 执行如下指令,完成maven 项目的打包,输出jar, 可以供其它模块使用(如图)

Maven教程--下(包括手动实现)_第7张图片

  1. 打包后,在target 目录生成对应的打包文件jar

Maven教程--下(包括手动实现)_第8张图片

完成安装

  1. 为了演示方便, 把当前maven 的settings.xml 的仓库恢复到默认的, 修改D:\program\apache-maven-3.6.3-bin\apache-maven-3.6.3\conf\settings.xml

Maven教程--下(包括手动实现)_第9张图片

  1. 执行install 指令,能完成maven 项目的安装,会把打包得到的jar, 提交到本地仓库

Maven教程--下(包括手动实现)_第10张图片

Maven教程--下(包括手动实现)_第11张图片

  1. 说明: 如果没有修改settings.xml 成默认的仓库路径, install 后, 生成的jar 会在指定的仓库路径下.
  2. 注意当把hello-project-1.0.jar 提交到本地仓库后,该jar 也可以被其他maven 项目使用了,非常方便

完成清理

  1. 执行如下指令,完成maven 项目的清理,会清除生成的target 目录

Maven教程--下(包括手动实现)_第12张图片

  1. 应用场景,比如我们希望把源码进行拷贝或移植, 或者希望来一次全新的bulid,就可以先进行clean

小结Maven 构建指令

● 说明: Maven 构建命令使用mvn 开头,后面添加功能参数,可以一次执行多个命令,使用空格分隔

mvn compile #编译
mvn clean #清理
mvn test #测试
mvn package #打包
mvn install #安装

IDEA 创建Maven Web 工程

需求说明/图解

使用IDEA 创建Maven WEB 项目, 可以运行hello,world 页面

注意体会Maven WEB 项目和前面创建的Maven java 项目不同

创建Maven web 项目

创建maven web 工程

web-hello-maven 工程

Maven教程--下(包括手动实现)_第13张图片

Maven教程--下(包括手动实现)_第14张图片

创建成功的maven web 项目结构

Maven教程--下(包括手动实现)_第15张图片

创建的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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>

  
  <groupId>com.wyxedugroupId>
  <artifactId>web-hello-mavenartifactId>
  <version>1.0-SNAPSHOTversion>
  <packaging>warpackaging>

  <name>web-hello-maven Maven Webappname>
  
  <url>http://www.example.comurl>

  
  <properties>
    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    <maven.compiler.source>1.8maven.compiler.source>
    <maven.compiler.target>1.8maven.compiler.target>
  properties>


  <dependencies>
    
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.11version>
      <scope>testscope>
    dependency>
  dependencies>

  

  <build>
    <finalName>web-hello-mavenfinalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-pluginartifactId>
          <version>3.1.0version>
        plugin>
        
        <plugin>
          <artifactId>maven-resources-pluginartifactId>
          <version>3.0.2version>
        plugin>
        <plugin>
          <artifactId>maven-compiler-pluginartifactId>
          <version>3.8.0version>
        plugin>
        <plugin>
          <artifactId>maven-surefire-pluginartifactId>
          <version>2.22.1version>
        plugin>
        <plugin>
          <artifactId>maven-war-pluginartifactId>
          <version>3.2.2version>
        plugin>
        <plugin>
          <artifactId>maven-install-pluginartifactId>
          <version>2.5.2version>
        plugin>
        <plugin>
          <artifactId>maven-deploy-pluginartifactId>
          <version>2.8.2version>
        plugin>
      plugins>
    pluginManagement>
  build>
project>

配置Tomcat 服务器&运行

  1. 为maven web 项目配置tomcat

Maven教程--下(包括手动实现)_第16张图片

Maven教程--下(包括手动实现)_第17张图片

Maven教程--下(包括手动实现)_第18张图片

war:先打包成war 包,再把该war 包部署到服务器上

war exploded:直接把文件夹、class 文件等等移到Tomcat 上进行部署。因此这种方式支持热部署,一般在开发的时候都是使用这种模式

Maven教程--下(包括手动实现)_第19张图片

依赖管理

依赖配置

一句话: 依赖指当前项目运行需要的jar,一个项目可以设置多个依赖

依赖的举例


<dependencies>
    
    <dependency>
        
        <groupId>junitgroupId>
        
        <artifactId>junitartifactId>
        
        <version>4.12version>
        <scope>testscope>
    dependency>
dependencies>

依赖传递

直接依赖

一句话: 在当前项目中通过依赖配置建立的依赖关系

举例说明

  1. 创建maven_A java 项目

Maven教程--下(包括手动实现)_第20张图片

  1. 在maven_A 项目中引入mysql5.1.47 , 这时我们就说maven_A 项目直接依赖mysql5.1.47jar
<dependencies>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.47version>
    dependency>
dependencies>
  1. 如图

Maven教程--下(包括手动实现)_第21张图片

间接依赖

一句话: 当前项目直接依赖资源(比如m1), 而m1 又依赖资源(m2),我们就说当前项目间接依赖资源(m2)

举例说明

  1. 创建maven_B java 模块(为了好理解,我们放在一个项目中)

Maven教程--下(包括手动实现)_第22张图片

Maven教程--下(包括手动实现)_第23张图片

Maven教程--下(包括手动实现)_第24张图片

Maven教程--下(包括手动实现)_第25张图片

Maven教程--下(包括手动实现)_第26张图片

  1. 修改D:\java_projects\maven_B\pom.xml , 引入junit4.12
<dependencies>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.12version>
    dependency>
dependencies>
  1. 修改D:\java_projects\maven_A\pom.xml , 引入maven_B
<dependencies>
    
    <dependency>
        <groupId>com.wyxgroupId>
        <artifactId>maven_BartifactId>
        <version>1.0-SNAPSHOTversion>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.47version>
    dependency>
dependencies>
  1. 观察maven_A 和maven_B 的依赖情况

Maven教程--下(包括手动实现)_第27张图片

依赖冲突

路径优先

  1. 路径优先∶当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
  2. 示意图说明:

Maven教程--下(包括手动实现)_第28张图片

  1. 解释项目A 依赖情况
    1. 如果1 度资源有junit 4.1 , 而2 度资源有junit4.2
    2. 根据路径优先原则, 项目A 生效的是junit4.1
  2. 举例说明.
  1. 创建maven_C(为了方便观察,仍然放在一个项目中), 创建方式和maven_B 类似,就不截图了

Maven教程--下(包括手动实现)_第29张图片

  1. 修改D:\java_projects\maven_C\pom.xml, 引入junit4.13
<dependencies>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.13version>
    dependency>
dependencies>
  1. 修改D:\java_projects\maven_B\pom.xml, 引入maven_C

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_BartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        
        <dependency>
            <groupId>com.wyxgroupId>
            <artifactId>maven_CartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
    dependencies>
project>
  1. 刷新工程,看看maven_A 生效的就是路径优先的maven_B 的junit4.12

Maven教程--下(包括手动实现)_第30张图片

  1. 为了验证是哪个junit 生效了, 还可以通过代码来验证, 写一段代码D:\java_projects\maven_A\src\main\java\HelloTest.java

Maven教程--下(包括手动实现)_第31张图片

声明优先

  1. 声明优先∶当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
  2. 示意图说明:

Maven教程--下(包括手动实现)_第32张图片

图解项目A 依赖情况

  1. 如果1 度(灰框)资源有junit 4.1 , 而1 度(蓝框)资源有junit4.2
  2. 根据声明优先原则, 要看项目A , 在pom.xml 引入的顺序,先引入的就是生效的
  1. 举例说明.
  1. 创建maven_D(为了方便观察,仍然放在一个项目中), 创建方式和maven_B 类似,就不截图了

Maven教程--下(包括手动实现)_第33张图片

  1. 修改D:\java_projects\maven_D\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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_DartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
        dependency>
    dependencies>
project>
  1. 修改D:\java_projects\maven_A\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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_AartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        
        <dependency>
            <groupId>com.wyxgroupId>
            <artifactId>maven_DartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>com.wyxgroupId>
            <artifactId>maven_BartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>
    dependencies>
project>

Maven教程--下(包括手动实现)_第34张图片

  1. 为了验证是junit4.13.2 生效还是junit4.12 生效, 写一段代码D:\java_projects\maven_A\src\main\java\HelloTest.java

Maven教程--下(包括手动实现)_第35张图片

特殊优先

  1. 特殊优先∶当同级配置了相同资源的不同版本,后配置的覆盖先配置的(提醒:要尽量避免这种没有意义的冲突)
  2. 修改D:\java_projects\maven_A\pom.xml, 引入mysql5.1

<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.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_AartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        
        <dependency>
            <groupId>com.wyxgroupId>
            <artifactId>maven_DartifactId>
        
            <version>1.0-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>com.wyxgroupId>
            <artifactId>maven_BartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.43version>
        dependency>
    dependencies>

project>
  1. 根据特殊优先原则: maven_A 生效的是mysql5.1.43

Maven教程--下(包括手动实现)_第36张图片

  1. 测试完后,注销到引入mysql5.1.43 , 这里是为了验证.

可选依赖

一句话: 可选依赖指对外隐藏当前所依赖的资源- 不透明

举例说明

  1. 需求: 隐藏maven_D 项目的junit 依赖,不让其他项目来使用
  2. 修改D:\java_projects\maven_D\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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_DartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            
            <optional>trueoptional>
        dependency>
    dependencies>
project>
  1. 刷新maven 管理器,看maven_A 的变化

Maven教程--下(包括手动实现)_第37张图片

  1. 测试完毕后,别忘了恢复原来状态.

排除依赖

一句话: 排除依赖指主动断开依赖的资源, 被排除的资源无需指定版本- 不需要

举例说明

  1. 需求: maven_A 项目主动排除maven_D 的junit4.13.2 这个依赖
  2. 修改D:\java_projects\maven_D\pom.xml

<dependency>
    <groupId>com.wyxgroupId>
    <artifactId>maven_DartifactId>
    <version>1.0-SNAPSHOTversion>
    
    <exclusions>
        <exclusion>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        exclusion>
    exclusions>
dependency>
  1. 刷新maven 管理器,看maven_A 的变化, 仍然是拿不到junti4.13.2, 提示: 再通过HelloTest.java 来验证实际使用的junit 版本, 更加清晰了.

Maven教程--下(包括手动实现)_第38张图片

可选依赖和排除依赖区别

一句话: 隐藏依赖是不让其他项目来引用(我不给), 排除依赖是主动不要引入的某个资源(我不要)

依赖范围

作用范围

一句话: 依赖的jar 默认情况可以在任何地方使用, 通过scope 标签设定其作用范围

举例说明

● 作用范围说明

  1. 主程序范围有效(src/main 文件夹范围内)
  2. 测试程序范围有效(src/test 文件夹范围内)
  3. 是否参与打包(package 指令范围内)
  4. compile(默认,在主程序、测试代码、打包都有效)

● 作用范围一览图

Maven教程--下(包括手动实现)_第39张图片

解读

  1. 某个引入的jar 包作用范围是程序员根据,业务的实际需要来设置的,不要认为是固定的。
  2. 比如log4j jar 包,在主程序,测试代码,打包都是需要的, 因此作用范围应当设置为complie
  3. junit 只是测试代码需要,因此作用范围设置为test 合适,但是如果程序员认为在主程序和打包就是要junit, 仍然可以设置为默认compile
  4. 比如servlet-api 是tomcat 自己带的,当把程序打包放到生产环境时,用生产环境tomcat 的servlet-api 即可,所以设置为provided 合适,这样就放在servlet-api 版本冲突.
  5. 比如jdbc, 是第三方的jar , 打包放在生产环境,就应当在自己的包提供jdbc 驱动包,否则程序会因为少驱动包,运行失败

● 看一个案例, 体会依赖范围的特点.


<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.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_DartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            
            <optional>falseoptional>
            
            <scope>testscope>
        dependency>
    dependencies>
project>
  1. 创建D:\java_projects\maven_D\src\test\java\T2.java, 在test 范围正常使用
import org.junit.Test;

public class T2 {
    @Test
    public void f1(){
    }
}
  1. 创建D:\java_projects\maven_D\src\main\java\T1.java, 在主程序中,报错

Maven教程--下(包括手动实现)_第40张图片

  1. 修改D:\java_projects\maven_D\pom.xml, 发现主程序和测试程序都可以使用了.
<optional>falseoptional>

<scope>compilescope>

Maven教程--下(包括手动实现)_第41张图片

Maven教程--下(包括手动实现)_第42张图片

  1. 运行maven web 项目

Maven教程--下(包括手动实现)_第43张图片

Maven 项目构建生命周期

一句话: Maven 构建生命周期描述的是一次构建过程经历了多少个事件

Maven教程--下(包括手动实现)_第44张图片

生命周期的3 大阶段

clean

清理工作

Maven教程--下(包括手动实现)_第45张图片

default

核心工作,例如编译,测试,打包,部署等

site

产生报告,发布站点等

Maven教程--下(包括手动实现)_第46张图片

生命周期是分阶段执行的

一句话: 项目构建生命周期分很多阶段,并不是每次都完整执行,而是根据用户的要求来执行的【比如你执行compile, 那么就执行到complie 这个阶段,如果你执行install, 则会执行compile->test->package->install】

举例说明

1、演示compile

Maven教程--下(包括手动实现)_第47张图片

2、演示install

Maven教程--下(包括手动实现)_第48张图片

maven 插件

介绍

1、插件与生命周期内的某个阶段绑定,在执行到对应生命周期时, 由对应插件来完成任务/功能.

2、maven 插件很多,先看一张图:

Maven教程--下(包括手动实现)_第49张图片

3、通过插件可以自定义其他功能

4、文档: http://maven.apache.org/plugins/index.html

自定义插件-应用实例

需求: 在pom.xml 加入自定义插件,能够在对maven_D 项目打包时,能输出主程序和测试程序的源码

完成步骤

  1. 当前package 只会得到项目的jar

Maven教程--下(包括手动实现)_第50张图片

  1. 修改D:\java_projects\maven_D\pom.xml, 加入maven 插件并配置(注意: 加入自定义插件后,可能会爆红,重启项目即可.)

<project xmlns="http://maven.apache.org/POM/4.0.0"
         韩顺平Java 工程师
         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.0modelVersion>
    <groupId>com.wyxgroupId>
    <artifactId>maven_DartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            
            <optional>falseoptional>
            
            <scope>compilescope>
        dependency>
    dependencies>
    
    <build>
        <plugins>
            <plugin>
                
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-source-pluginartifactId>
                <version>2.2.1version>
                <executions>
                    <execution>
                        <goals>
                            
                            <goal>jargoal>
                            
                            <goal>test-jargoal>
                        goals>
                        
                        <phase>generate-test-resourcesphase>
                    execution>
                executions>
            plugin>
        plugins>
    build>
project>
  1. 观察一下maven 项目管理器

Maven教程--下(包括手动实现)_第51张图片

  1. 再次执行maven-D 的intall 操作, 会得到两个新的jar ,分别包含了主程序和测试程序的源码。(说明: 测试时,需要保证src/main/… 和src/test/… 两个目录下有java 源代码,否则不会生成源码jar)

Maven教程--下(包括手动实现)_第52张图片

  1. 解压得到jar , 可以看到源码了.

Maven教程--下(包括手动实现)_第53张图片

maven 插件-maven 构建生命周期关系图

Maven教程--下(包括手动实现)_第54张图片

图解

  1. 在maven 项目构建生命周期中,每个阶段的执行都有相应的插件完成

  2. 各个插件执行过程中,会附带输出内容,比如jar/war/xml/源码

  3. 程序员可以使用maven 默认的插件,也可以自定义插件,完成定制任务.

  4. 自定义插件引入成功, 是可以看到

Maven教程--下(包括手动实现)_第55张图片

你可能感兴趣的:(常用工具,maven,junit,java,服务器,运维)