Maven详解

Lou.Chen
大约 18 分钟

一、Maven构建项目主要步骤

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

**②编译:**将 Java 源程序编译为字节码文件。

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

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

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

**⑥安装:**在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。

**⑦部署:**将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。

二、Maven仓库/插件镜像配置

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!--本地仓库路径-->
  <localRepository>D:/maven-repository</localRepository>
  <mirrors>
	    <!-- 阿里镜像及其他插件镜像的配置 -->
		<mirror>
			<id>alimaven</id>
			<mirrorOf>central</mirrorOf>
			<name>aliyun maven</name>
			<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
		</mirror>
		<mirror>
			<id>alimaven</id>
			<name>aliyun maven</name>
			<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
			<mirrorOf>central</mirrorOf>
		</mirror>
		<mirror>
			<id>central</id>
			<name>Maven Repository Switchboard</name>
			<url>http://repo1.maven.org/maven2/</url>
			<mirrorOf>central</mirrorOf>
		</mirror>
		<mirror>
			<id>repo2</id>
			<mirrorOf>central</mirrorOf>
			<name>Human Readable Name for this Mirror.</name>
			<url>http://repo2.maven.org/maven2/</url>
		</mirror>
		<mirror>
			<id>ibiblio</id>
			<mirrorOf>central</mirrorOf>
			<name>Human Readable Name for this Mirror.</name>
			<url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>
		</mirror>
		<mirror>
			<id>jboss-public-repository-group</id>
			<mirrorOf>central</mirrorOf>
			<name>JBoss Public Repository Group</name>
			<url>http://repository.jboss.org/nexus/content/groups/public</url>
		</mirror>
		<mirror>
			<id>google-maven-central</id>
			<name>Google Maven Central</name>
			<url>https://maven-central.storage.googleapis.com
			</url>
			<mirrorOf>central</mirrorOf>
		</mirror>
		<!-- 中央仓库在中国的镜像 -->
		<mirror>
			<id>maven.net.cn</id>
			<name>oneof the central mirrors in china</name>
			<url>http://maven.net.cn/content/groups/public/</url>
			<mirrorOf>central</mirrorOf>
		</mirror>
  </mirrors>
  <profiles>
    <!--编译配置-->
	<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>
  </profiles>

三、Maven基本命令

1、查看maven版本

mvn -v

2、生成项目编译后的文件

mvn complie

3、生成编译后的测试文件

mvn test-compile

4、打包到当前项目下

mvn package

5、打包到当前项目和本地仓库

mvn install

  • 当前项目下
  • 本地仓库下

5、删除当前项目下target的所有文件

mvn clean

6、部署到私服(自动部署)

mvn deploy

四、Maven坐标(gav)

使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。

  • groupid:公司或组织的域名倒序+当前项目名称

  • artifactId:当前项目的模块名称

  • version:当前模块的版本

    <groupId>org.lc</groupId>
    <artifactId>firstproject</artifactId>
    <version>1.0-SNAPSHOT</version>

当我们执行mvn install生成项目的jar包后存储在本地仓库的路径形式为:

  • 本地仓库路径/{groupId}/{artifactId}/{version}/{artifactId}-{version}.jar
    • 本地仓库路径/org/lc/firstproject/1.0-SNAPSHOT/firstproject-1.0-SNAPSHOT.jar

五、Maven依赖管理

1、自定义jar并被其他项目使用

1)创建maven工程,写完功能后执行mvn install打包到本地仓库中

  • 要打包的jar的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>org.lc</groupId>
    <artifactId>secondproject</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>
  • 在本地仓库中生成的jar

2)引用在本地仓库中的jar进行使用

<?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>org.lc</groupId>
    <artifactId>firstproject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
		<!--和jar创建的时候的pom的groupId,artifactId,version一致-->
        <dependency>
            <groupId>org.lc</groupId>
            <artifactId>secondproject</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2、依赖范围scope

1)compile
  • 在主程序有效
  • 测试程序有效
  • 并参与部署(打包)
2)test

只在test阶段有依赖关系,例如junit

  • 在主程序无效
  • 测试程序有效
  • 不参与部署(打包)
3)provided

在runtime时并不输出依赖关系而是由容器提供,例如web war包都不包括servlet-api.jar,而是由tomcat等容器来提供

  • 在主程序有效
  • 测试程序有效
  • 不参与部署(打包)
4)runtime

编译的时候是用不到的,但是在运行的时候会用到,如在连接mysql中的JDBC

  • 在主程序(编译)无效
  • 测试程序有效
  • 并参与部署(打包)
5)system

system范围依赖与provide类似,但是必须显示的提供一个对于本地系统中jar文件的路径。一般不推荐使用。

依赖范围主程序运行(编译)测试程序运行时(打包)例子
compilespring-core
testjunit
providedservlet-api(由打包后的tomcat容器提供)
runtimeJDBC驱动
system本地的,Maven之外地的仓库

3、依赖的传递性

默认的依赖包括compile具有传递性,非compile的依赖没有传递性

A 依赖 B,B 依赖 C,A 能否使用 C 呢?那要看 B 依赖 C 的范围是不是 compile,如果是则可用,否则不 可用。

4、依赖的排除

在mysql-connector-java的工程下的pom.xml中

  <dependencies>
    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>3.6.1</version>
    </dependency>
  </dependencies>

排除我们当前工程下的mysql-connector-java中的protobuf-java依赖

		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
            <scope>runtime</scope>
            <exclusions>
                <exclusion>
                    <artifactId>protobuf-java</artifactId>
                    <groupId>com.google.protobuf</groupId>
                </exclusion>
            </exclusions>
        </dependency>

六、Maven执行的生命周期

https://www.cnblogs.com/huxinga/p/6740897.htmlopen in new window

​ Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。

​ Maven的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由插件完成,类似于设计模式中的模板方法。

1、三套独立的生命周期

分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。

**1)clean **清理项目

  • pre-clean:执行清理前需要完成的工作

  • clean:清理上一次构建生成的文件

  • post-clean:执行清理后需要完成的工作

2)default生命周期:构建项目

  • validate:验证工程是否正确,所有需要的资源是否可用。
  • compile:编译项目的源代码。
  • test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
  • Package:把已编译的代码打包成可发布的格式,比如jar。
  • integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
  • verify:运行所有检查,验证包是否有效且达到质量标准。
  • install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
  • Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。

3)site生命周期:建立和发布项目站点

  • pre-site:生成项目站点之前需要完成的工作

  • site:生成项目站点文档

  • post-site:生成项目站点之后需要完成的工作

  • site-deploy:将项目站点发布到服务器

2、命令行和生命周期

各个生命周期相互独立,一个生命周期的阶段前后依赖。

  • mvn clean

    • 调用clean生命周期的clean阶段,实际执行pre-clean和clean阶段
  • mvn test

    • 调用default生命周期的test阶段,实际执行test以及之前所有阶段
  • mvn clean install

    • 调用clean生命周期的clean阶段和default的install阶段,实际执行pre-clean和clean,install以及之前所有阶段

七、统一管理版本

<?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>org.lc</groupId>
    <artifactId>secondproject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--以properties创建标签-->
    <properties>
        <!--自定义版本号标签-->
        <spring-version>5.2.6.RELEASE</spring-version>
        <mysql.connection.version>5.1.47</mysql.connection.version>
        <junit-version>4.13</junit-version>
    </properties>

    <dependencies>
        <!--直接使用 ${标签名称} -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connection.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

八、依赖的基础dependencyManagement

<?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>org.lc</groupId>
    <artifactId>secondproject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--依赖关联的版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>5.2.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>5.2.7.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--若没有写版本号 则会使用dependencyManagement中定义的版本号-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <!--若没有写版本号 则会使用dependencyManagement中定义的版本号-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        <!--若写了verson版本号,则优先使用本标签定义的版本号-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>
</project>

九、聚合工程

这里我们以SpringBoot工程为例

1、父工程mall

<?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>
        <!--springboot版本统一管理 相当于dependencyManagement-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!--统一版本-->
        <version>2.2.7.RELEASE</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>mall</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    
    <modules>
        <module>mallmail</module>
        <module>mailserver</module>
    </modules>
</project>
1)子工程mallmail
<?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>mall</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mallmail</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mail-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
2)子工程mailserver
<?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>mall</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mailserver</artifactId>
    <packaging>pom</packaging>
    
    <modules>
        <module>mail-commons</module>
        <module>mail-model</module>
        <module>mail-mapper</module>
        <module>mail-service</module>
        <module>mail-web</module>
    </modules>
</project>
①mail-commons
<?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>mailserver</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mail-commons</artifactId>

</project>
②mail-mapper
<?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>mailserver</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mail-commons</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mail-model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
③mail-model
<?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>mailserver</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mail-model</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mail-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
④mail-service
<?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>mailserver</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mail-service</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mail-mapper</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
⑤mail-web
<?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>mailserver</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mail-web</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mail-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2、工程的打包和部署

  • 若我们要部署程序,则直接打包父工程mall即可,其他工程也就随之打包
  • 若我们在各模块直接要相互引入不同的模块,则直接在dependencies中引用即可
1)解决maven循环依赖的问题
  • 每个模块的依赖情况
  • 修改模块的依赖情况
  • 刷新maven即可

3、包导入后还是无法找到依赖包

第一步:找到settings

第二步:点击 右下角的APPLY 然后OK

十、nexus私服的使用

https://www.cnblogs.com/endv/p/11204704.htmlopen in new window

1、私服的作用

一般用作局域网,是种特殊的Maven仓库一般用于公司,比如三十个员工开发一个项目,需要每个人都联网去下载jar,每个人都很痛苦。此时公司可以搭建一个私服,让其中一人去私服下载jar,这样私服中就缓存了那些jar包,其他人在下载的时候就无需重新从远程仓库下载了,直接从私服缓存的地方拿下来即可。

2、Maven仓库的分类

  • 本地仓库
  • 远程仓库
    • 中央仓库
    • 私服
    • 其它公共库。

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

3、windows下的nexus的使用

1)下载后解压的文件夹
2)初始化启动

在bin目录下 nexus.exe /run

  • 这个过程可能比较耗时,需等待
3)修改账号和访问地址
4)添加用户
5)仓库类型说明
6)修改中央仓库镜像
7)服务安装和卸载

**注意:**若安装服务失败,则以管理员身份启动此命令提示符

  • 安装服务

    • nexus /install
  • 启动服务

    • nexus /start
  • 停止服务

    • nexus /stop
  • 卸载服务

    • nexus /uninstall
8)创建私服文件的存放地址
9)创建代理资源库

十一、常见问题

1、多模块打包找不到依赖

Failed to execute goal on project ...: Could not resolve dependencies for project

https://blog.csdn.net/two_people/article/details/77883208open in new window

先打包父项目

参考:https://blog.csdn.net/two_people/article/details/77883208open in new window

2、以UTF-8编译

Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependen

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

3、若出现maven插件找不到

[ERROR] Plugin org.apache.maven.plugins:maven-dependency-plugin:2.8 or one o ...

直接到maven仓库删除指定D:\maven-repository\org\apache\maven\plugins\路径下的maven-dependency-plugin文件夹即可

4、各版本号含义

Alpha、Beta、Gamma、PRE版本

Alpha:内测版,BUG多,开发人员开发过程中使用,希腊字母α,第一,指最初版

Beta:早期版本,有缺陷,无大BUG,可能加入新功能,进一步开发完善。

PRE: 预览版,内部测试版。主要是给开发人员和测试人员测试和找BUG用的,不建议使用;

Gamma : 经beta 版,完善修改,成为正式发布的候选版本(Release Candidate)

RC、GA、R版本

RC:(Release Candidate):候选版本,几乎就是正式版了, GA:(Ggeneral Availability):发行稳定版,官方推荐使用此版本。 R,RELEASE:正式版,等价于GA

SNAPSHOT版本

SNAPSHOT:快照版,可以稳定使用,且仍在继续改进版本。

快照版和正式版的区别?

  • 快照版本和正式版本的主要区别在于,本地获取这些依赖的机制有所不同。假设你依赖一个库的正式版本,构建的时候构建工具会先在本次仓库中查找是否已经有了这个依赖库,如果没有的话才会去远程仓库中去拉取。所以假设你发布了Junit-4.10.jar到了远程仓库,有一个项目依赖了这个库,它第一次构建的时候会把该库从远程仓库中下载到本地仓库缓存,以后再次构建都不会去访问远程仓库了。所以如果你修改了代码,向远程仓库中发布了新的软件包,但仍然叫Junit-4.10.jar,那么依赖这个库的项目就无法得到最新更新。你只有在重新发布的时候升级版本,比如叫做Junit-4.11.jar,然后通知依赖该库的项目组也修改依赖版本为Junit-4.11,这样才能使用到你最新添加的功能。
  • 这种方式在团队内部开发的时候会变的特别蛋痛。假设有两个小组负责维护两个组件,example-service和example-ui,其中example-ui项目依赖于example-service。而这两个项目每天都会构建多次,如果每次构建你都要升级example-service的版本,那么你会疯掉。这个时候SNAPSHOT版本就派上用场了。每天日常构建时你可以构建example-service的快照版本,比如example-service-1.0-SNAPSHOT.jar,而example-ui依赖该快照版本。每次example-ui构建时,会优先去远程仓库中查看是否有最新的example-service-1.0-SNAPSHOT.jar,如果有则下载下来使用。即使本地仓库中已经有了example-service-1.0-SNAPSHOT.jar,它也会尝试去远程仓库中查看同名的jar是否是最新的。有的人可能会问,这样不就不能充分利用本地仓库的缓存机制了吗?别着急,Maven比我们想象中的要聪明。在配置Maven的Repository的时候中有个配置项,可以配置对于SNAPSHOT版本向远程仓库中查找的频率。频率共有四种,分别是always、daily、interval、never。当本地仓库中存在需要的依赖项目时,always是每次都去远程仓库查看是否有更新,daily是只在第一次的时候查看是否有更新,当天的其它时候则不会查看;interval允许设置一个分钟为单位的间隔时间,在这个间隔时间内只会去远程仓库中查找一次,never是不会去远程仓库中查找(这种就和正式版本的行为一样了)。

5、packaging标签详解

<packaging>pom</packaging>
<packaging>jar</packaging>
<packaging>war</packaging>

pom

​ 在父级项目中的pom.xml文件使用的packaging配置一定为pom。父级的pom文件只作项目的子模块的整合,在maven install时不会生成jar/war压缩包。

​ 一定有童鞋会问:为什么需要一个父级pom文件呢? 好处如下:

  • 可以通过<modules>标签来整合子模块的编译顺序(Maven引入依赖使用最短路径原则,例如a<–b<–c1.0 ,d<–e<–f<–c1.1,由于路径最短,最终引入的为c1.0;但路径长度相同时,则会引入先申明的依赖)。因此尽量将更加底层的service放在更先的位置优先加载依赖较为合适。
  • 可以将一些子项目中共用的依赖或将其版本统一写到父级配置中,以便统一管理。
  • groupId, artifactId, version能直接从父级继承,减少子项目的pom配置。

jar

Jar包是最为常见的打包方式,当pom文件中没有设置packaging参数时,默认使用jar方式打包。 这种打包方式意味着在maven build时会将这个项目中的所有java文件都进行编译形成.class文件,且按照原来的java文件层级结构放置,最终压缩为一个jar文件。

当我们使用mvn install命令的时候,能够发现在项目中与src文件夹同级新生成了一个target文件夹,这个文件夹内的classes文件夹即为刚才提到的编译后形成的文件夹

class文件会放在BOOT-INF下

jar文件像是一个工具包,可被其他服务通过依赖引用,也可通过jar命令启动

war

war包与jar包非常相似,同样是编译后的.class文件按层级结构形成文件树后打包形成的压缩包。

不能通过依赖去引用此包,适用于发布web项目的入口,class文件会放在WEB-INF下

war常用于java web工程,但也不是绝对的,war也可以用java -jar xxx.war执行,前提是你有配置main函数入口