# 基础

Maven是appache下的开源项目,项目管理工具,管理Java项目

  • 本地仓库:第一次会从远程仓库下载jar包,保存在本地。下次先从本地找,找不到再去远程仓库找
  • 远程仓库:自己架设的仓库,对外公开
  • 中央仓库 (opens new window):maven团队维护的仓库,用户只能下载,不能添加

# 安装配置

  • 第一步 下载maven

    • 官方下载链接 (opens new window)
    • Binary可执行版本,已编译好的可以直接使用
    • Source源代码版本,需自己编译成可执行软件才可使用
    • 我们选择已经编译好的windows版本进行安装:选择zip版本(linux选择tar.gz)
  • 第二步 maven环境配置

    • 系统变量:MAVEN_HOME=D:\maven\apache-maven-3.8.4
    • 变量Path:添加 %MAVEN_HOME%\bin
    • 验证maven环境配置是否成功:mvn -version
  • 第三步 配置maven仓库以及相关设置

    • 配置maven仓库,创建一个maven仓库目录
    • 配置settings.xml:
      //找到节点localRepository,在注释外添加自己仓库的地址
      <localRepository>D:\JAVA\apache-maven\apache-maven-3.8.5</localRepository>
      
      //配置阿里云镜像
      <mirror>
      <id>alimaven</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
      </mirror>
      
      //配置JDK
      <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>
      
    • 配置完成。输入命令:mvn help:system 测试
  • 第四步 添加maven到我们的IDEA中

    • 点击File的setting,设置IDEA的maven指向我们自己的maven地址 maven

# 项目结构

maven

  • test目录发布时不会被打包
  • 手动添加的resources文件夹需要点击右键Mark Directory as -> Resources Root

# 父工程与子模块显示在同一层级

父工程与子模块显示在同一层级

# 常用命令

在生命周期中,执行后边的命令,会自动执行前面的命令

  • clean:清除编译的target目录
  • compile:编译命令,将src/main/java下的文件编译为class文件输出到target目录下
  • test:运行所有的测试方法
  • package:打包命令,在target目录下会出现war包/jar包
  • install:将当前项目安装到本地仓库中,其他项目引用本项目的jar包时不用去私服上下载jar包

# 创建项目

  • Java项目:archetype(骨架) -> maven-archetype-quickstart
  • WEB项目:archetype(骨架) -> maven-archetype-webapp
  • MVC项目:先创建WEB项目,Project Structure - Modules - 添加Java/Resource文件夹 - Mask as

# Pom.xml配置

  • 依赖项:资源的唯一标识(groupId->atifactId->version maven中的路径)
    • groupId:组织名 org.example
    • atifactId:模块名称 maven-test1
    • version:版本号
    • packaging:打包类型 war/jar/pom
    • scope:依赖范围
  • 插件
    • Alt+Insert 快捷键添加
    <build>
      <plugins>
      	<plugin>
      		<groupId>org.apache.tomcat.maven</groupId>
      		<artifactId>tomcat7-maven-plugin</artifactId>
      		<version>2.2</version>
      		<configuration>
      		  <port>80</port>
      		  <path>/</path>
      		</configuration>
      	  </plugin>
      </plugins>
    <build>
    

# 依赖范围

maven

  • compile 编译、测试、运行
    • 比如:strus-core、spring-beans
    • 打到war包或jar包
  • provided 编译、测试有效
    • 比如:servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)。
    • 不会打到war包
  • runtime:运行、测试有效
    • 比如:jdbc驱动包,在开发代码中针对java的jdbc接口开发,编译不用,在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库
    • 会打到war包
  • test:只是测试有效,只在单元测试类中用
    • 比如:junit
    • 不会打到war包
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.6</version>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>servlet-api</artifactId>
	<version>2.5</version>
	<scope>provided</scope>
</dependency>

注意

  • 如果是compile就不需要设置了,因为compile是scope的默认值
  • Tomcat中包含servlet-api,所以设置为provided,防止运行时有冲突

# pom.xml 中的 scope import 解析

使用 scope import 可以解决 Maven 的单继承问题

Maven 本身支持继承,很多时候我们会创建多模块项目,而多个模块会引入相同的依赖项,这个时候我们就可以使用 Maven 的父子工程结构。创建一个父 pom.xml,其他项目中的 pom.xml 文件继承父 pom.xml,子模块的 pom.xml 的内容如下图所示:

<parent>
    <groupId>com</groupId>
	<artifactId>springboot_dubbo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</parent>

通过上面这种方式,就可以使我们的依赖项管理更加调理。但是 Maven 父子项目结构和 Java 继承一样,都是单继承,一个子项目只能制定一个父 pom ,很多时候,我们需要打破这种单继承。

例如使用 spring-boot 的时候,官方推荐的方式是继承父 pom ,如下图所示:

<parent>
    <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.4.RELEASE</version>
</parent>

但是如果项目中已经有了其他父 pom ,又想用 spring-boot 怎么办?这个时候就需要使用 scope import ,还需要指定 type pom ,如下图所示:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.4.RELEASE</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

注意

scope import 只能在 dependencyManagement 模块中使用

# 将项目本身编译并打包到本地仓库

将下载的jar包放到一个你知道的位置,比如我放在D:/maven/repository/ojdbc6.jar 然后打开cmd,执行mvn install:install-file -Dfile=/D:/maven/repository/ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1.0 -Dpackaging=jar -DgeneratePom=true

maven-install

命令中的参数具体指的是什么内容:

  • install:可以将项目本身编译并打包到本地仓库
  • install-file:安装文件
    • Dfile=D:\ojdbc6.jar:指定要打的包的文件位置
    • DgroupId=com.oracle:指定当前包的groupId为com.oracle
    • DartifactId=ojdbc6:指定当前的artifactfactId为ojdbc6
    • Dversion=11.2.0.1.0:指定当前包的版本为11.2.0.1.0
    • DgeneratePom=true:是否生成pom文件

根据install位置找到需要的jar,将他放在你的maven本地仓库指定路径D:\maven\repository\com\oracle\ojdbc\ojdbc6\11.2.0.1.0,最后我们引入就好了

# 修改项目的打包名称

<build>
  <!-- 服务打包的最终名称 -->
  <finalName>app</finalName>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

# 高级

# 分模块开发

将原始模块按照功能拆分成若干个子模块,项目中的每一层都可以单独维护,也可以很方便的被别人使用

分模块开发

  • ssm_pojo项目中创建com.itheima.domain包,并将maven_02_ssm中Book类拷贝到该包中
  • 删除原项目ssm中的domain包
  • 在ssm项目的pom.xml添加ssm_pojo的依赖
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>ssm_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
  • 使用maven的install命令,把其安装到Maven的本地仓库中
  • 再次执行ssm的compile的命令后,就已经能够成功编译

# 依赖管理

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

<!--设置当前项目所依赖的所有jar-->
<dependencies>
    <!--设置具体的依赖-->
    <dependency>
        <!--依赖所属群组id-->
        <groupId>org.springframework</groupId>
        <!--依赖所属项目id-->
        <artifactId>spring-webmvc</artifactId>
        <!--依赖版本号-->
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

# 依赖传递

  • 依赖中箭头 > 的含义:这个依赖还依赖了其他依赖
  • 依赖是具有传递性的。可以把maven_02_ssm项目中pom.xml关于maven_03_pojo的依赖注释或删除掉

依赖是具有传递性的

# 依赖冲突

这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突

  • 同级特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
  • 不同级路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
  • 如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies

依赖冲突

# 可选依赖和排除依赖

  • 可选依赖指对外隐藏当前所依赖的资源---不透明
<!--在maven_04_dao的pom.xml,在引入maven_03_pojo的时候,添加optional-->
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_03_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--可选依赖是隐藏当前工程所依赖的资源,隐藏后的资源不再具有依赖传递性-->
	<!--当前项目可用,引用当前项目的不再能用-->
    <optional>true</optional>
</dependency>
  • 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本---不需要
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_04_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--已经有依赖的事实,排除依赖是隐藏对当前资源的依赖关系-->
    <exclusions>
        <exclusion>
            <groupId>com.itheima</groupId>
            <artifactId>maven_03_pojo</artifactId>
        </exclusion>
    </exclusions>
</dependency>

# 聚合

  • 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合
  • 聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)

具体实现 :

  • 创建一个空的maven项目
  • 将项目的打包方式改为pom
<?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.itheima</groupId>
    <artifactId>maven_01_parent</artifactId>
    <version>1.0-RELEASE</version>
    <packaging>pom</packaging>
    
</project>

项目的打包方式,我们接触到的有三种,分别是

  • jar:默认情况,说明该项目为java项目
  • war:说明该项目为web项目
  • pom:说明该项目为聚合或继承(后面会讲)项目
  • 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.itheima</groupId>
    <artifactId>maven_01_parent</artifactId>
    <version>1.0-RELEASE</version>
    <packaging>pom</packaging>
    
    <!--设置管理的模块名称,module顺序不重要,系统会根据依赖关系来自动决定执行的顺序-->
	<!--各模块都在当前pom.xml的父目录一级-->
    <modules>
        <module>../maven_02_ssm</module>
        <module>../maven_03_pojo</module>
        <module>../maven_04_dao</module>
    </modules>
</project>

# 继承

与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承

实现步骤:

  • 创建Maven模块,设置打包类型为pom
  • 在父工程的pom文件中配置共用的依赖,一般只抽取子项目中公有的jar包
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    ...
</dependencies>
  • 在父工程中配置依赖管理,提供可选择的依赖资源,让子工程中可以按需引用
<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_01_parent</artifactId>
    <version>1.0-RELEASE</version>
    <!--快速找到父工程的pom文件的相关路径,可以不写-->
    <relativePath>../maven_01_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>
    <mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>
  • 修改依赖的version
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>

# 配置文件加载属性

  • 父工程定义属性
<properties>
   <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
</properties>
  • jdbc.properties文件中引用属性
<!--在jdbc.properties,将jdbc.url的值直接获取Maven配置的属性-->
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
  • 设置maven过滤文件范围
<!--Maven在默认情况下是从当前项目的src\main\resources下读取文件进行打包-->
<!--现在我们需要打包的资源文件是在maven_02_ssm下,需要我们通过配置来指定下具体的资源目录-->
<build>
    <resources>
        <!--设置资源目录-->
        <resource>
		     <!--
			${project.basedir}: 当前项目所在目录,相当于所有的子项目都添加了资源目录的过滤
             -->
            <directory>${project.basedir}/src/main/resources</directory>
            <!--设置能够解析${},默认是false -->
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
  • 打包的过程中如果报缺少web.xml
    • 解决方案1:在maven_02_ssm项目的src\main\webapp\WEB-INF\添加一个web.xml文件
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
      	                       http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
      						   
             version="3.1">
      	   
    </web-app>
    
    • 解决方案2: maven_02_ssm配置maven打包war时,忽略web.xml检查,failOnMissingWebXml
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

# 版本

  • SNAPSHOT(快照版本):项目开发过程中临时输出的版本,称为快照版本
  • RELEASE(发布版本)
  • alpha版:内测版,bug多不稳定内部版本不断添加新功能
  • beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能
  • 纯数字版

# 多环境开发

  • 父工程配置多个环境,并指定默认激活环境
<profiles>
    <!--开发环境env_dep-->
    <profile>
        <id>env_dep</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
        </properties>
        <!--设定是否为默认启动环境-->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!--生产环境env_pro-->
    <profile>
        <id>env_pro</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
        </properties>
		<!--设定是否为默认启动环境-->
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
    </profile>
    <!--测试环境env_test-->
    <profile>
        <id>env_test</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
        </properties>
    </profile>
</profiles>
  • 命令行实现环境切换
mvn 指令 -P 环境定义ID[环境定义中获取]
mvn install -P env_test

# 跳过测试

  • 方式一:IDEA工具实现跳过测试按钮Toggle'Skip Tests'
  • 方式二:配置插件实现跳过测试
<build>
    <plugins>
        <plugin>
            <!--maven测试插件,因为是内部插件,所以不用提高groupId-->
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <skipTests>false</skipTests>
                <!--
				skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试
				excludes:哪些测试类不参与测试,即排除,针对skipTests为false来设置的
				includes: 哪些测试类要参与测试,即包含,针对skipTests为true来设置的
				-->
                <excludes>
                    <exclude>**/BookServiceTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 方式三:命令行跳过测试
mvn 指令 -D skipTests
mvn package -D skipTests

# 私服

私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题

Nexus是Sonatype公司的一款maven私服产品 下载地址 (opens new window)

  • 使用cmd进入到解压目录下的bin,执行如下命令启动nexus服务器
nexus.exe /run nexus
  • 访问地址为
http://localhost:8081
  • 首次登录重置密码
用户名:admin  密码:根据登录提示进入文件查看初始密码
  • 修改基础配置信息
etc目录中nexus-default.properties

注意

安装路径不能有中文

# 私服仓库的分类

  • 宿主仓库hosted(用于上传)
    • 小组内自己用的,自主研发的
    • 无法从中央仓库获取的资源,比如Oracle,因为是付费产品,所以中央仓库没有
  • 代理仓库proxy(用于下载)
    • 所有项目组公用的,仓库组内只有一个
    • 代理远程仓库,转调中央仓库,通过nexus访问中央仓库
  • 仓库组group(用于下载)
    • 将若干个仓库组成一个群组,用来打包下载
    • 仓库组不能保存资源,属于设计型仓库

私服仓库的分类

# 本地仓库访问私服配置

  • 私服上配置仓库:创建名为xxx-snapshot和xxx-release宿主仓库hosted
  • 配置本地Maven对私服的访问权限
<!--在本地Maven的配置文件settings.xml中进行配置-->
<servers>
    <server>
        <id>itheima-snapshot</id>
        <username>admin</username>
        <password>admin</password>
    </server>
    <server>
        <id>itheima-release</id>
        <username>admin</username>
        <password>admin</password>
    </server>
</servers>
  • 配置私服的访问路径
<!--在本地Maven的配置文件settings.xml中进行配置-->
<mirrors>
    <mirror>
        <!--配置仓库组的ID-->
        <id>maven-public</id>
        <!--*代表所有内容都从私服获取-->
        <mirrorOf>*</mirrorOf>
        <!--私服仓库组maven-public的访问路径-->
        <url>http://localhost:8081/repository/maven-public/</url>
    </mirror>
</mirrors>

配置私服的访问路径

# 私服资源上传与下载

  • 配置工程上传私服的具体位置
 <!--配置当前工程保存在私服中的具体位置-->
<distributionManagement>
    <repository>
        <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
        <id>itheima-release</id>
         <!--release版本上传仓库的具体地址-->
        <url>http://localhost:8081/repository/itheima-release/</url>
    </repository>
    <snapshotRepository>
        <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
        <id>itheima-snapshot</id>
        <!--snapshot版本上传仓库的具体地址-->
        <url>http://localhost:8081/repository/itheima-snapshot/</url>
    </snapshotRepository>
</distributionManagement>
  • 发布资源到私服或者执行Maven命令
mvn deploy
  • 现在发布是在itheima-snapshot仓库中,如果想发布到itheima-release仓库中就需要将父工程和子模块parent标签里继承父工程parent中的version修改成RELEASE即可。
<groupId>com.itheima</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<packaging>pom</packaging>
	
	
<parent>
    <groupId>com.itheima</groupId>
    <artifactId>maven_01_parent</artifactId>
    <version>1.0-RELEASE</version>
    <!--快速找到父工程的pom文件的相关路径,可以不写-->
    <relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>

注意

要发布的项目都需要配置分配管理distributionManagement标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可

# 私服配置阿里云镜像

如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。 私服配置阿里云镜像