妈妈再也不用担心我不会maven了

587 阅读5分钟

   Maven的核心功能便是搭建项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包,怎么通过pom.xml的配置就可以获取到jar包呢?pom.xml配置文件从何而来?等等类似问题我们需要搞清楚,如果需要使用pom.xml来获取jar包,那么首先该项目就必须为maven项目,maven项目可以这样去想,就是在java项目和web项目的上面包裹了一层maven,本质上java项目还是java项目,web项目还是web项目,但是包裹了maven之后,就可以使用maven提供的一些功能了(通过pom.xml添加jar包)。

第一步:

导入maven依赖发生了什么。

我们写了如下的一个pom依赖

      

      通常情况下,我们利用 groupId、artifactId、version 标签来确认这个依赖的唯一坐标,就像我们在坐标系用YXZ来定位某一个点一样。

       当我们拿到这个坐标之后去本地仓库找这个依赖(就是找jar包),本地仓库(每个电脑默认的仓库是在 $user.home/.m2/repository下)。没有就去私服仓库(一般是由公司自己设立的,只为本公司内部共享使用。它既可以作为公司内部构件协作和存档,也可作为公用类库镜像缓存,减少在外部访问和下载的频率。使用私服为了减少对中央仓库的访问,私服可以使用的是局域网,中央仓库必须使用外网,也就是一般公司都会创建这种第三方仓库,保证项目开发时,项目所需用的jar都从该仓库中拿,每个人的版本就都一样。注意:连接私服,需要单独配置。如果没有配置私服,默认不使用),没有再去中央仓库(就是网站repo1.maven.org/maven2)寻找,再…

第二步:

maven找到引入后,再讲下maven的生命周期。

maven的生命周期如下:maven的生命周期就如IDEA中显示的那样,顺序由上至下。

  • clean: 移除所有上一次构建生成的文件
  • validate:验证工程是否正确,所有需要的资源是否可用
  • **compile:**编译项目的源代码
  • **test:**使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
  • **package:**把已编译的代码打包成可发布的格式,比如 jar、war 等。
  • **verify:**运行所有检查,验证包是否有效且达到质量标准。
  • **install:**把包安装到maven本地仓库,可以被其他工程作为依赖来使用
  • site: 生成项目的站点文档
  • deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。

注意一点_:_从下到下是由一个执行包含关系,比如我执行clean,就只会执行clean功能,移除构建文件。但是如果我执行compile,那它就会执行clean、validate、compile三条命令。

第三步

最后再讲一下maven如何排除依赖,这也是平时使用maven比较头疼的一点。

方法一:使用IDEA插件maven helper。

     不会还有人不会下载使用IDEA插件吧,  不会吧,不会吧。

     maven helper插件安装成功,点开pom.xml会发现多了一个Dependency Analyzer视图,如下:

上面按钮的图标含义如下

  • Conflicts(查看冲突)
  • All Dependencies as List(列表形式查看所有依赖)
  • All Dependencies as Tree(树形式查看所有依赖)

上图说明有3个jar存在冲突,点击冲突的jar,可以查看和哪个jar产生冲突,如下图

方法二:在IDEA下的Terminal下输入如下命令:mvn -Dverbose dependency:tree 

(maven已经添加环境依赖为前提)

  就可以看到该项目的依赖树了,如下:

出现这种的就是出现了依赖冲突,有些并不会报错,除非你是处女座看不惯,否者没必要去除。

发现了冲突,怎么解决呢?

方法一:使用maven helper

切换到maven 依赖视图选择冲突选项,如果有冲突,在左下面区域会有红色显示。

解决冲突,右键单击红色区域,弹出菜单选择Exclude命令,对冲突进行排除。

排除完效果如下:

<dependency> 
     <groupId>com.juejin.business</groupId>
     <artifactId>juejin-image-web</artifactId>
     <version>1.0.0-SNAPSHOT</version>
     <exclusions> 
        <exclusion> 
         <groupId>com.juejin.business</groupId>
         <artifactId>juejin-convert-web</artifactId> 
         </exclusion>
     </exclusions> 
 </dependency>

方法二:

或者我们可以直接在pom文件下加入

它产生的效果和使用插件是一样:

<dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
         <version>5.2.7.RELEASE</version>
          <exclusions>
           <exclusion>
           <artifactId>spring-core</artifactId>
           <groupId>org.springframework</groupId>
           </exclusion>
        </exclusions>
 </dependency>

或者使用optionnal将该依赖设置为可选的**(optional是maven依赖jar时的一个选项,表示该依赖是可选的.不会被依赖传递)**

<dependency>   
   <groupId>com.juejin.business</groupId>  
   <artifactId>juejin-convert-web</artifactId> 
    <version>1.0.0-SNAPSHOT</version>  
    <optional>true</optional>
</dependency>

为什么要使用optional

  • 减少不必要的依赖传递
  • 减少jar包冲突

例如

  • B依赖了日志框架 logback、log4j、apache commons log
  • 这时候的依赖关系如下 A->B

因为maven有依赖传递机制.那么A项目就会有3个jar包,logback、log4japache commons log.实际上我们一般只会在项目中使用一种日志框架.那么我们项目中就会有多余的依赖.当这种情况时越来越多时,最后整个项目的jar包就有很多的多余依赖,导致项目很臃肿.

如何优化

只要B项目中把logback、log4j、apache commons log设置成<optional>true</optional>

例如

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <optional>true</optional>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <optional>true</optional>
</dependency>

这时候A项目依赖B的时候,项目中不会有logback、log4japache commons log jar包,可以根据情况自行选择一个即可.

下班时间到了,就写到这吧,下次再讲。