Maven入门实战

Maven是什么?

Maven是一个项目管理和综合工具。Maven提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。

在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建报表,检查,构建和测试自动化设置。

PS:在我们的日常开发当中,Maven 主要的作用是为了管理项目中依赖包(包含公司内部依赖包,外部第三方依赖),项目构建等操作。

Maven的优势

1. Maven不仅是构建工具,它还是依赖管理工具和项目管理工具,提供了中央仓库,能够帮我们自动下载构件。

2.为了解决的依赖的增多,版本不一致,版本冲突,依赖臃肿等问题,它通过一个坐标系统来精确地定位每一个构件(artifact)。

3.还能帮助我们分散在各个角落的项目信息,包括项目描述,开发者列表,版本控制系统,许可证,缺陷管理系统地址。

4.项目非常大时,可借助Maven将一个项目拆分成多个工程,最好是一个模块对应一个工程,利于分工协作。而且模块之间还是可以发送消息的。

5.maven对于目录结构有要求,约定优于配置,用户在项目间切换就省去了学习成本。

Maven安装

Windows:

1.下载对应文件,http://maven.apache.org/download

2.解压缩安装包到你想安装的目录

D:\apache-maven-3.5.4

3.配置环境变量

MAVEN_HOME
D:\apache-maven-3.5.4
PATH
%MAVEN_HOME%\bin;

4.验证安装

mvn -version

Linux:

1.下载文件

cd /usr/local
mkdir maven
cd maven
wget  http://mirrors.cnnic.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz

2.解压缩安装包到你想安装的目录

tar -zxvf apache-maven-3.5.4-bin.tar.gz

3.配置环境变量

vim /etc/profile

增加下面内容
export MAVEN_HOME=/usr/local/maven/apache-maven-3.5.4
export PATH=${PATH}:${MAVEN_HOME}/bin

4.验证安装

mvn -version

Maven文件目录分析

bin
boot
conf
lib
LICENSE.txt
NOTICE.txt

1.bin :存放可执行脚本,包含Linux和Windows系统。

2.boot:仅仅存在一个plexus-classworlds-x.x.x.jar 文件,一个类加载器框架,一般不需要关注它。

3.conf:这里主要保存了Maven配置的setting.xml 文件,这个文件对于我们十分重要,一般情况下,每个公司的环境都要去修改它,在idea中可以设置全局配置指定配置其配置文件。

4.lib: Maven 运行时需要的 Java 类库。

PS:通常情况下我们仅需要关注conf文件夹下的setting文件。

Maven使用

1.Maven结构目录

单module结构

|---src                     源码

|---|---main                存放主程序
|---|---|---java            存放Java源代码
|---|---|---resources       存放框架或者其他工具的配置文件

|---|---test                存放测试程序
|---|---|---java            存放Java测试的源代码
|---|---|---resources       存放测试的配置文件

|---pom.xml                 Maven工程的核心配置文件

当然了,实际开发中另一种常见的是多个module形式的

|---ModuleA
|---ModuleB
|---pom.xml

通常会指定ModuleA 和ModuleB中的父类pom为最外层的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.huaxia</groupId>
    <artifactId>mavendemo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>moduleA</module>
        <module>moduleB</module>
    </modules>


</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">
    <parent>
        <artifactId>mavendemo</artifactId>
        <groupId>com.huaxia</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>moduleB</artifactId>


</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">
    <parent>
        <artifactId>mavendemo</artifactId>
        <groupId>com.huaxia</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>moduleA</artifactId>


</project>

2.pom.xml解析

Maven 项目的核心是 pom.xml。POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构
建,声明项目依赖,等等。

我们可以根据上面的父类为例,来分析pom文件的各个属性和其含义

代码的第一行是 XML 头,指定了该 xml 文档的版本和编码方式。紧接着是 project 元素,
project 是所有 pom.xml 的根元素,它还声明了一些 POM 相关的命名空间及 xsd 元素,虽
然这些属性不是必须的,但使用这些属性能够让第三方工具(如 IDE 中的 XML 编辑器)
帮助我们快速编辑 POM。
根元素下的第一个子元素 modelVersion 指定了当前 POM 模型的版本,对于 Maven2 及
Maven 3 来说,它只能是 4.0.0。

groupId,artifactId 和 version 三行是Maven世界的三围坐标系,Maven基于它们对于项目进行区分。

groupId 定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。

artifactId 定义了当前 Maven 项目在组中唯一的 ID。

version 指定了 项目当前的版本——1.0-SNAPSHOT。SNAPSHOT 意为快照,说明该项目还处于开发中,是不稳定的版本。RELEASE为稳定版本,正式发布时应该更改为RELEASE版本,关于SNAPSHOT和RELEASE的问题,我们在打包发布的环境会有详细的讲解。

packaging为打包的类型,通常有jar,war,pom类型。

modules包含了子项目信息(如果子项目之间有依赖关系,那么module的顺序是有要求的,moduleA会比mduleB先编译)

以上内容为最基础的内容,在一个项目中,还会包含其他的配置信息。

下面我们来新建一个spingBoot项目,然后来逐步分析其配置

在父类pom中加入

 <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

利用idea新建一个springBoot项目,起名为demo,并指定其父类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>

    <artifactId>demo</artifactId>

    <packaging>jar</packaging>

    <name>demo</name>

    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.huaxia</groupId>
        <artifactId>mavendemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

父pom:

这里我们采用了非spring官方的父类pom文件的形式,所以在父类pom文件中指明了所依赖的关于springBoot的各个版本,并在子项目中配置各种依赖包,这样做的好处是项目pom文件可以指定继承pom文件,每个公司内部都应该编写一个一个统一的父类pom文件并继承它,这样可以大大减少实际项目中pom文件的复杂性和相关依赖包的各个版本不同导致的兼容性问题,减少每个项目的工作量,规范代码等待好处。

子pom:

properties:pom中的属性声明,通常我们应该把它放到父pom中,其中,各个软件的版本号通常也用properties 声明

例如:

<?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.huaxia</groupId>
    <artifactId>mavendemo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>moduleA</module>
        <module>moduleB</module>
        <module>demo</module>
    </modules>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <springboot.version>2.0.5.RELEASE</springboot.version>
        <demo.version>1.0-SNAPSHOT</demo.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springboot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.huaxia</groupId>
                <artifactId>demo</artifactId>
                <version>${demo.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

2.1.1dependencies解析

根元素 project 下的 dependencies 可以包含一个或者多个 dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:

groupId、artifactId 和 version:依赖的基本坐标,对于任何一个依赖来说,基本坐标
是最重要的,Maven 根据坐标才能找到需要的依赖。
type:依赖的类型,对应于项目坐标定义的 packaging。大部分情况下,该元素不必声
明,其默认值为 jar。
scope:依赖的范围。
optional:标记依赖是否可选。
exclusions:用来排除传递性依赖。

大部分依赖声明只包含基本坐标,然而在一些特殊情况下,其它元素至关重要,下面会对它们的原理和使用方式详细介绍。

scope 依赖范围

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

首先需要知道,Maven 在编译项目主代码的时候需要使用一套 classpath。Maven 在编译和执行测试的时候会使用另外一套 classpath,该依赖仅仅存在于测试环境的classpath中(classpath存在3种,编译,测试,运行)。

依赖范围就是用来控制依赖与这 3 种 classpath(编译 classpath、测试 classpath、运行classpath)的关系,Maven 有以下几种依赖范围:

Compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的 Maven 依赖,对于编译、测试、运行三种 classpath 都有效在编译、测试和运行的时候都需要使用该依赖。

Test:测试依赖范围。使用此依赖范围的 Maven 依赖,只对于测试 classpath 有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子是 JUnit,它只有在编译测试代码及运行测试的时候才需要。

Provided:已提供依赖范围。使用此依赖范围的 Maven 依赖,对于编译和测试classpath 有效,但在运行时无效。典型的例子是 servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要 Maven 重复的引入一遍。

Runtime:运行时依赖范围。使用此依赖范围的 Maven 依赖,对于测试和运行classpath 有效,但在编译主代码时无效。典型的例子是 JDBC 驱动实现,项目主代码的编译只需要 JDK 提供的 JDBC 接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体 JDBC 驱动。

System:系统依赖范围。该依赖与 3 种 classpath 的关系,和 Provided 依赖范围完全一致。但是,使用 System 范围的依赖时必须通过 systemPath 元素显式地指定依赖文件的路径。由于此类依赖不是通过 Maven 仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。

Import:(Maven 2.0.9 及以上):导入依赖范围。该依赖范围不会对 3 种 classpath 产生
实际的影响。上文中springboot的引用环境就使用了这个配置,后面会讲解。

2.1.2依赖传递性

依赖范围不仅可以控制依赖与 3 种 classpath 的关系,还对传递性依赖产生影响。

假设 A 依赖于 B,B 依赖于 C,我们说 A 对于 B 是第一直接依赖,B 对于 C 是第二直接依赖,A 对于 C 是传递性依赖。

如下图所示:第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围,如表 3-2 所示,最左边一行表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围:

                compile         test        provided      runtime
compile         compile         -           -             runtime    
test            test            -           -             test     
provided        provided        -           provided      provided
runtime         runtime         -           -             runtime

当第二直接依赖的范围是 compile 的时候,传递性依赖的范围与第一直接依赖的范围一致;当第二直接依赖的范围是 test 的时候,依赖不会得以传递;当第二直接依赖的范围是 provided 的时候,只传递第一直接依赖范围也为 provided 的依赖,且传递性依赖的范围同样为 provided;当第二直接依赖的范围是runtime 的时候,传递性依赖的范围与第一直接依赖的范围一致,但 compile 例外,此时传递性依赖的范围为 runtime。

例:

<?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">
    <parent>
        <artifactId>mavendemo</artifactId>
        <groupId>com.huaxia</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>moduleA</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.huaxia</groupId>
            <artifactId>demo</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</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>

    <artifactId>demo</artifactId>

    <packaging>jar</packaging>

    <name>demo</name>

    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.huaxia</groupId>
        <artifactId>mavendemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>



    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

moduleA依赖了demo,依赖范围是test,那么demo中的spring-boot-starter-web依赖(默认为compile)在moduleA中的依赖传递就是test。

2.1.3.可选依赖

2.1.4.排除依赖

有时候第三方的依赖传递会出现不同版本的依赖,比如A项目中引用了mybatis 3.4.2 ,而 B项目中引用了mybatis 3.4.5,然后A又引用了B,这样在A项目中就出出现mybatis3.4.2和 mybatis3.4.5 2个版本的依赖,这种时候会造成jar包的混乱,有可能会导致一些莫名其妙的bug问题(后文我会讲解类似情况遇到的一个问题),所以排除依赖也是很有必要的。

排除依赖的例子:

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

2.1.5.归类依赖

为了使依赖的版本方便管理升级,我们通常的做法是对依赖进行归类,这里给大家列出比较好的方式:

<?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.huaxia</groupId>
    <artifactId>mavendemo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>demo</module>
        <module>moduleA</module>
        <module>moduleB</module>
    </modules>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <springboot.version>2.0.5.RELEASE</springboot.version>
        <demo.version>1.0-SNAPSHOT</demo.version>
        <lombok.version>1.18.2</lombok.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springboot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <dependency>
                <groupId>com.huaxia</groupId>
                <artifactId>demo</artifactId>
                <version>${demo.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

这里面,子项目的所有依赖都用dependencyManagement 元素来控制其版本(这里dependencyManagement这个元素仅仅是声明这个依赖的信息,并不是真正的引用,注意和dependencies的区别)

子项目中一定都会用到的依赖应该在父类中用dependencies元素声明,(dependencies确定引用这个依赖,对应的子项目即使没有声明,也会引用)

依赖的版本号通过用${}符号抽取变量,方便日后升级。

2.2.1.依赖仓库

在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。

Maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库。(仓库就是存放依赖和插件的地方)

仓库分类:

1.本地仓库

2.远程仓库,又包含以下内容

2.1.中央仓库

2.2.私服

2.3.其他公共库

本地仓库

maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository/的仓库目录,这就是Maven仓库的默认位置

maven的settings.xml文件中,有本地仓库的设置,在idea中的Maven插件中也可以设置仓库的位置

例:

  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository -->
  <localRepository>E:\Repository\HuaXiaRepository</localRepository>

远程仓库

说到远程仓库先从 最核心的中央仓库开始,中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置

<repositories>  
    <repository>  
      <id>central</id>  
      <name>Central Repository</name>  
      <url>http://repo.maven.apache.org/maven2</url>  
      <layout>default</layout>  
      <snapshots>  
        <enabled>false</enabled>  
      </snapshots>  
    </repository>  
</repositories>

私服

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

Maven私服的 个特性:

1.节省自己的外网带宽:减少重复请求造成的外网带宽消耗

2.加速Maven构件:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低

3.部署第三方构件:有些构件无法从外部仓库获得的时候,我们可以把这些构件部署到内部仓库(私服)中,供内部maven项目使用

4.提高稳定性,增强控制:Internet不稳定的时候,maven构建也会变的不稳定,一些私服软件还提供了其他的功能

5.降低中央仓库的负荷:maven中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力

远程仓库配置

pom文件里:

<repositories>
....
    <repository>
      <id>jboss</id>
      <name>JBoss Repository</name>
      <url>https://repository.jboss.com/maven2/</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
     <releases>
        <enabled>true</enabled>
      </releases>
    </repository>
 ....
</repositories>

远程仓库的认证

大部分公共的远程仓库无须认证就可以直接访问,但我们在平时的开发中往往会架设自己的Maven远程仓库,出于安全方面的考虑,我们需要提供认证信息才能访问这样的远程仓库。配置认证信息和配置远程仓库不同,远程仓库可以直接在pom.xml中配置,但是认证信息必须配置在settings.xml文件中。这是因为pom往往是被提交到代码仓库中供所有成员访问的,而settings.xml一般只存在于本机。因此,在settings.xml中配置认证信息更为安全。

<settings>
     ...
     <!--配置远程仓库认证信息-->
     <servers>
          <server>
             <id>releases</id>
             <username>admin</username>
             <password>admin123</password>
        </server>
     </servers>
     ...
</settings>

配置远程仓库的镜像

镜像的一个常见的用法是结合私服。由于私服可以代理任何外部的公共仓库(包括中央仓库),因此,对于组织内部的Maven用户来说,使用一个私服地址就等于使用了所有需要的外部仓库,这可以将配置集中到私服,从而简化Maven本身的配置。在这种情况下,任何需要的构件都可以从私服获得,私服就是所有仓库的镜像。这时,可以配置这样的一个镜像:

<!--配置私服镜像-->
<mirrors> 
    <mirror>  
        <id>nexus</id>  
        <name>internal nexus repository</name>  
        <url>http://183.238.2.182:8081/nexus/content/groups/public/</url>  
        <mirrorOf>*</mirrorOf>  
    </mirror>  
</mirrors>

从仓库解析依赖的机制

当依赖范围是 system 时候,Maven直接从本地文件解析构件。
根据依赖坐标计算仓库路径后,先从本地仓库寻找构件,如果发现则解析成功。
本地仓库没找到,如果依赖版本(version)是发布版构件,即1.2,2.3等,则遍历远程仓库,发现后下载并解析使用。
如果version是SNAPSHOT版,如:2.1-SNAPSHOT,则基于更新策略(updatepolicy)读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载。(如果最新版还是之前的值就不需要去远程仓库下载了)。 
注意:这一步因为updatepolicy的原因,可能要求本机能连接到远程仓库(远程仓库可以是私服或者中央仓库,一般只有自己的项目会使用SNAPSHOT,所以大多数是私服)
如果最后解析得到构件版本是时间戳格式的快照,如1.4.1-20161121.121432-121则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该时间戳格式的构件。
当依赖的version值为RELEASE时(不建议),Maven会基于updatepolicy策略读取远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库相对应元数据合并后,计算出最新版本的RELEASE值(稳定版),然后基于这个值检查本地和远程仓库,步骤如2和3。 
注意:存在潜在问题,如某个依赖的1.1版本与1.2版本可能发生一些接口变化,从而导致当前Maven项目构建失败,所以依赖的版本最好确定。

2.3.1.build元素

build元素平时开发中常用的有  <resources>  <plugin> ,下面我们来介绍一下

 resource

 一个resources元素的列表。每一个都描述与项目关联的文件是什么和在哪里

  targetPath

  指定build后的resource存放的文件夹,默认是basedir。通常被打包在jar中的resources的目标路径是META-INF

  directory

  定义resource文件所在的文件夹,默认为${basedir}/src/main/resources

  includes

  指定哪些文件将被匹配,以*作为通配符

  excludes

  指定哪些文件将被忽略

plugin 

build中插件的配置根据插件不同而不同,这里我举个例子

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Class-Path>.</Class-Path>
                        </manifestEntries>
                    </archive>
                    <excludes>
                        <exclude>application.properties</exclude>
                        <exclude>application*.properties</exclude>
                        <exclude>logback*.xml</exclude>
                    </excludes>
                </configuration>
            </plugin>

这里面就是生成jar包时候不包含配置文件,可以避免因为配置文件的原因影响到各个环境,而且保证了本地idea里面运行时候会包含配置文件。

2.4.1. profiles

这里我给大家一个例子详解

pom.xml

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <profile.active>dev</profile.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>sit</id>
            <properties>
                <profile.active>sit</profile.active>
            </properties>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
        </profile>
    </profiles>

application.properties

spring.profiles.active=@profile.active@

application-dev.properties

server.port=8080

application-sit.properties

server.port=9090

pom文件里定义了两套profile 属性,并且在application.properties里面用引用了变量

在我们默认打包的时候,application.properties里会生成spring.profiles.active=dev

而如果指定profile 打包(mvn clean package -P sit)便会生成spring.profiles.active=sit

可以用于不同环境的打包需求。

PS:如有类似配置,idea中直接运行程序是会有问题的,未采用mvn的编译,导致profile属性失效,需要手动运行package命令生成一次class文件即可。

如果出现profile配置失效情况,可以增加以下插件解决

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                            <resources>
                                <resource>
                                    <!-- 指定resources插件处理哪个目录下的资源文件 -->
                                    <directory>src/main/resources</directory>
                                    <filtering>true</filtering>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

3.Maven命令

package、install、deploy的联系与区别

我们在用maven构建java项目时,最常用的打包命令有mvn package、mvn install、deploy,这三个命令都可完成打jar包或war(当然也可以是其它形式的包)的功能,但这三个命令还是有区别的。

mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。
mvn clean install依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段。
mvn clean deploy依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段。

由上面的分析可知主要区别如下,

package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库。
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以按照以下步骤来创建一个简单的Spring Boot注册项目: 1. 在你的IDE中创建一个新的Spring Boot项目。你可以选择使用Spring Initializr(https://start.spring.io/)来快速生成项目模板,或者手动创建一个新的Maven或Gradle项目并添加必要的依赖。 2. 在你的项目中创建一个User类,表示用户对象。可以包含属性如id、username和password等。 3. 创建一个UserController类,用于处理用户注册的请求和逻辑。可以使用@RequestMapping注解来指定请求路径和方法。 ```java @RestController @RequestMapping("/api/users") public class UserController { @PostMapping("/register") public String registerUser(@RequestBody User user) { // 在这里处理用户注册逻辑 // 可以将用户信息保存到数据库或执行其他操作 return "User registered successfully!"; } } ``` 4. 配置数据库连接。在application.properties或application.yml文件中添加数据库连接配置,包括数据库URL、用户名和密码等。 5. 创建一个UserRepository接口,继承自Spring Data JPA的CrudRepository接口,用于操作数据库。 ```java @Repository public interface UserRepository extends CrudRepository<User, Long> { // 在这里添加自定义的查询方法 } ``` 6. 在UserController类中注入UserRepository,并在注册方法中使用它进行数据库操作。 ```java @RestController @RequestMapping("/api/users") public class UserController { private final UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @PostMapping("/register") public String registerUser(@RequestBody User user) { userRepository.save(user); return "User registered successfully!"; } } ``` 7. 运行你的Spring Boot应用程序,可以使用Postman或其他工具发送POST请求到`/api/users/register`路径,并传递一个包含用户信息的JSON对象作为请求体。 这只是一个简单的示例,你可以根据需求进一步完善和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值