Maven总结

Maven

  • 为什么要用Maven?
    • 在平时的开发当中,肯定会导入各种的第三方jar包,这些jar包之间会存在依赖关系.,而这些包之间还会存在版本兼容的问题,所以,对于包的管理就显得特别重要了
    • 如果没有maven,你可能会经历如下的艰苦过程:
      • 当jar包有依赖的时候,要去挨着下载对应的jar包
      • 当jar包依赖有冲突的时候,要去挨个排查是哪里出的问题
      • 当项目有新人加入的时候,要去拷贝大量的jar包,进行重复构建
  • 什么是Maven?
    • Maven是一个java项目管理工具,主要功能是统一开发规范与包的管理

    • 项目构建工具:

      • 用来将源代码构建成可以发布的构建工具.
    • 依赖管理工具

      • 用来管理jar包之间的依赖,只需要在指定的pom.xml文件中写入这些jar包的依赖属性,就会自动进行下载管理这些jar包.

      • pom.xml: 项目对象模型

        <-- 依赖导入:通过坐标来进行注入 -->
        <dependencies>
           <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>5.2.0.RELEASE</version>
            </dependency>
        
      ````
    • 项目信息聚合工具:

      • 管理项目的信息相关内容,开发者信息,版本号等
  • Maven的安装和配置
    • 官网下载maven的安装包:

      http://maven.apache.org/download.cgi

    • 配置环境变量:(类似于jdk的配置)

      • 新建系统环境变量MAVEN_HOME,变量值填写maven的安装路径,不到bin.
      • 找到Path环境变量: 在变量值后面加%MAVEN_HOME%/bin;.
      • 验证: cmd输入 maven -version,出现maven的版本信息,说明安装成功
    • 配置maven的本地仓库:

      • 如果不配置本地仓库,那么会自动将远程下载的jar包放在如下位置

        C:\Users\Administrator.m2\repository;

      • 打开maven的安装目录,找到conf下的settings.xml,打开.

      • 找到配置文件中的

        <localRepository>/path/to/local/repo</localRepository>
        <-- 这段配置信息在注释里面,将其复制放出来,在路径填写你的本地仓库路径 -->
        <localRepository>D:\userData\repo</localRepository>
        
    • 配置maven的中央仓库:

      • 当在构建maven项目的时候,会先检查pom.xml文件,确定依赖包的位置将其下载:

        • 首先会在本地仓库中查找获取依赖包,如果没有,则往下执行
        • 从中央仓库查找获取依赖包,如果没有,则往下执行
        • 如果在pom.xml中定了自定义的远程仓库,那么也会在这里的仓库中查找获取依赖包,如果都没找到,maven会抛出异常
      • 配置中央仓库:这里建议使用阿里云的中央仓库

        <mirror>
        		<id>aliyunmaven</id>
        		<mirrorOf>*</mirrorOf>
        		<name>阿里云公共仓库</name>
        	<url>https://maven.aliyun.com/repository/public</url>
        </mirror>
        
  • 使用命令行创建maven项目
    • 输入命令:mvn archetype:generate ,回车,然后会出现选择骨架的选项( 默认是7 ),可以在上面信息看到 7:xxxxxx-quickstart ,这个表示你将要创建的是一个java项目,回车即可.
    • 如果你需要创建javaWeb项目,则输入10, 这个选项是 10:xxxx-webapp ,表示你将要创建的是一个javaWeb项目,回车即可.
    • 输入项目坐标:
      • 第一个: groupId ,这个表示你的组织号,例如你是哪一个公司的等 com.li
      • 第二个: artifactId ,这个表示项目名, mavendemo
      • 第三个: version ,表示版本号
      • 第四个: package,表示包结构
      • 回车即可
  • maven创建的项目的目录结构
    • javaSe项目目录:

      • src(项目源码) ->
        • main(业务代码) , test(测试代码) ->
          • java(核心代码) ,resources(配置文件,例如spring的xml配置文件,properties文件)->
            • 包路径 -> java类
    • javaWeb项目目录:

      • 与java项目相比,在main里面多了webapp目录
  • 依赖范围:
    •  <-- 通过scope来指定依赖范围 ->
       <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>	
         </dependency>
      
      
    • 什么是依赖范围?

      • maven项目不同阶段引入到classpath中的依赖是不同的,例如,编译时,maven会将编译相关的依赖引入classpath中,测试时,maven会将测试相关的依赖引入到classpath中,运行时,则会将运行时相关的依赖引入classpath中,依赖范围就是用来控制依赖于这三种classpath的关系的

      • 有哪些依赖范围?

        • compile : 编译依赖范围 :该范围就是默认的依赖范围(不写scope就是默认),此依赖对于编译,测试,运行三种classpath都有效,会随着项目一起打包发布,例如:springframwork

           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-core</artifactId>
               <version>2.5</version>
               <scope>compile</scope> <!--默认为该依赖范围,无须显示指定--〉
              </dependency>
          
        • test : 测试依赖范围 : 这个范围是针对测试的,只对测试classpath才有效,在编译主代码和运行项目的时候,都无法使用该依赖,不会随着项目发布,例如:junit

           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.7</version>
              <scope>test</scope>
              </dependency>
          
        • runtime : 运行时依赖范围 : 使用该范围的依赖只对测试和运行时的classpath有效,对编译时是无效的.例如JDBC驱动,适用运行和测试阶段.

          不过runtime的地方改成compile也不会出大问题.

           <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
                  <scope>runtime</scope>
              </dependency>
          
        • provided :环境提供依赖范围 : 使用该范围的依赖,只对编译和测试的classpath有效,对运行的classpath无效,最直接的例子就是servlet-api,在项目编译和测试的时候需要用到该依赖,但是在运行时,web容器(tomcat)已经提供了该依赖,如果不显示指定这个依赖范围的话,那么可能会由于tomcat依赖的版本不一样而造成版本冲突的情况:

           <dependency>
               <groupId>javax-servlet</groupId>
               <artifactId>servlet-api</artifactId>
               <version>2.0</version>
              <scope>provided</scope>
           </dependency>
          
        • system : 系统依赖范围 :该范围与provided所表示的依赖范围一致,只是system必须通过systemPath元素显式的指定依赖文件的路径,并不是通过maven仓库解析的,往往与本机系统进行绑定,可能会造成构建的不可移植性( 系统的不同,Windows与Linux之类的 ),所以,需要谨慎的使用(一般不用)

  • 依赖继承
    • 在maven项目中,子项目可以继承父项目中的依赖;
    • 比如我们有一个父项目( maven-father),该父项目有一个子项目( maven-child),父项目中引入了依赖junit,就算在子项目中我们没有引入junit依赖,但是我们依旧能够在子项目中使用junit,因为子项目天然继承了父项目中的junit依赖,在Idea中,我们可以查看子项目的依赖结构图,可以看到子项目中含有junit依赖
  • 依赖传递
    • 在maven项目中,依赖是可以传递的;

    • 有三个项目A,B,C. A -> B ->C,项目A依赖项目B,项目B依赖项目C,那么可以得出项目A依赖项目C( A ->C )

    • 下面贴上依赖关系的代码:

      <-- 项目A: -->
      <dependencies>
          <dependency>
              <groupId>com.li</groupId>
              <artifactId>B</artifactId>
              <version>1.0-SNAPSHOT</version>
          </dependency>
      </dependencies>
      
      项目B:
      <dependencies>
          <dependency>
              <groupId>com.li</groupId>
              <artifactId>C</artifactId>
              <version>1.0-SNAPSHOT</version>
          </dependency>
      </dependencies>
      
      项目C:
      <dependencies>
      </dependencies>
      
    • 进行测试:

      在项目C中写入如下代码:
      public class DoIt(){
          public String doI(){
              return "C项目中的dotest";
          }
      }
      在C项目中测试类中写如下代码:
      public class TestDoIt(){
          public void test(){
              DoIt doIt=new DoIt();
              doIt.doI();
          }
      }
      在C项目中运行测试代码,会在控制台输出 : 'C项目中的dotest'
      
    • 我们将C项目中的测试代码复制到A项目和B项目里面进行运行,可以看见控制台也会打印出 C项目中的dotest这样一句话,在A项目和B项目里面并没有DoIt这个类, 这就验证了 依赖的传递的这个性质了.

  • 能进行依赖传递的前提:
    • 只有依赖范围为compile和runtime的依赖是传递的
  • 依赖传递的一些规则:
    • 简单传递依赖:
      • A -> B -> C => A-B A ->C
    • 最短路径原则:
      • 谁离得近就使用谁的依赖( jar包 )
      • A到C的路径为 :A ->B ->C
      • A到B的路径为: A ->B
      • 如果C中使用的druid版本是 1.0
      • B中使用的druid版本是 1.1
      • 那么根据最短路径原则,A中依赖的druid版本就是1.1
    • 第一声明优先原则:
      • 当路径长度相同的时候,会使用到第一声明优先原则
      • A -> B -> C(1.0)
      • A -> D ->C(2.0)
      • 此时A ->C(1.0)和C(2.0)的依赖路径是一样的,在pom中,谁写在前面就会决定使用谁的依赖
  • 排除依赖传递
    • 使用 exclusions声明不需要传递的依赖

    • A -> B ,项目A依赖与项目B,通过依赖的传递,项目B中的jar包会传递到A当中来.

    • 如果项目A中与项目B中使用了相同的版本号不同的jar包,那么此时就会出现依赖冲突,就可以使用 exclusions标签来将项目B中不想他传递的jar包包起来;

      <dependency>
          
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
          
        <-- 不想其依赖传递的一些jar包 -->
        <exclusions>	
          <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
          </exclusion>
        </exclusions>
          
      </dependency>
      
      
      
  • 版本管理器(dependencyManagement )
    • 在maven中, dependecyManagement 这个标签相当于对所依赖jar包的管理器,只做声明;

    • pom中,jar的版本判断有两种方式:

      • 如果在dependencies中有自己声明version元素,那么不管 dependencyManagement 里面有没有对该jar版本的声明都会以 dependencies里面的version为准.
      • 如果在 dependencies里面没有对导入的依赖声明 version,那么maven就会根据 groupIdartifactIddependencyManagement里面找有没有对此jar包的声明,如果有就继承这个version,没有机会报错.
    • dependencyManagement只是声明依赖,并不会实现依赖的引入,因此子项目需要显示声明需要用的依赖. 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本 .

      <-- 只是对版本进行管理,不会实际引入jar -->
      <dependencyManagement>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>5.2.0.RELEASE</version>
          </dependency>
      </dependencyManagement> 
      
      <-- 会实际下载jar包 -->
      <dependencies> 
             <dependency> 
                <groupId>org.springframework</groupId>
             	 <artifactId>spring-context</artifactId>
             </dependency> 
      </dependencies>
      
  • maven中的常用命令
    • maven clean : 对项目进行清理,清理的过程中会删除targt目录下编译的内容
    • maven compile : 编译项目源代码 , 编译后的内容会存放在target目录下
    • maven test : 对项目的运行进行测试
    • maven packet : 将项目打包,打包后的文件会存放到项目的target目录下,打包好的文件通常都是编译后生成的class文件
    • maven install : 将自定义的maven项目,安装至本地仓库,可以供其他项目使用
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值