zoukankan      html  css  js  c++  java
  • Maven的基础了解与使用

    首发日期:2018-11-04


    Maven的介绍:

    什么是Maven:

    • Maven是apache旗下的一个java开源项目。
    • Maven是一个项目管理工具,它可以帮助我们管理项目
    • 可以使用Maven对java项目进行项目构建(构建包括清理、编译、测试、报告、打包、部署六个过程,你可以认为是一个项目的从代码到完整可运行项目的过程)、依赖管理。

    为什么要学习maven?

    以一个例子说一下maven的好处,说了它的好处,

    1.maven可以帮我们管理依赖。在以往的时候,我们都是手动的导入jar包,然后build path;在导入jar包之前,我们需要去查找有哪些包,需要哪些包,这是一个非常繁杂的问题,如果你不是“老司机”的话,你可能会遗漏某些jar包;而在maven中,我们可以使用pom.xml来声明需要哪些依赖包,然后maven就会根据pom.xml中的信息去获取仓库中的依赖包的引用,这就相当于导入了jar包。而且,maven存储了大量的jar包和大量的依赖规则,所以你可以直接去百度搜索一下某个关键字+maven,就可以查找到某个框架或工具的依赖信息,直接把这个依赖信息拷贝到pom.xml中,maven就会帮你管理这个依赖。

    2.maven可以帮我们进行工程管理。在以往的时候,我们开发一个项目都是在一个工程中开发,但事实上这对多人开发并不友好,多个开发者之间的开发产生了耦合关系,这对整合造成了一些小困扰(但并不是说不好,只是说有更好的手段)。而使用maven之后,可以建立多个工程来组成一个项目,在不同的工程中开发不同的模块,而多个工程之间的关系由maven管理,maven可以帮我们把多个工程组合成一个项目。



    安装与配置:


    下载:

    点击链接,下载Maven:

    下载完了之后,直接解压即可,它是免安装的。


    配置环境变量

    • 配置JAVA_HOME环境变量,值是jdk程序根目录【如果已经配置过的,可以省略】

    • %JAVA_HOME%in添加到path环境变量中【如果已经配置过的,可以省略】【注意不要弄乱了path的值】

    • 配置MAVEN_HOME环境变量,值是maven程序根目录

    • %MAVEN_HOME%in添加到path环境变量中【注意不要弄乱了path的值】

    测试安装结果:

    配置了环境变量后,可以在CMD中键入mvn -v来测试是否可以运行,下面是我的输出结果:

    Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
    Maven home: J:softwareapache-maven-3.5.4in..
    Java version: 1.8.0_91, vendor: Oracle Corporation, runtime: E:SOFTWARDJavajdk1.8.0_91jre
    Default locale: zh_CN, platform encoding: GBK
    OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
    

    Maven概念:

    在学会maven之前,先了解几个概念。下面的概念了解即可,后面会在实际的配置中涉及。

    坐标

    在以往的build path过程中,其实只是把jar包的路径引用添加到eclipse中,eclipse知道需要的包的路径之后,在编译的时候会去引用。

    而maven可以根据坐标来指定使用哪个依赖包,坐标经过一定的组合规则就可以得出依赖包所在的路径,maven会根据坐标对应的路径在仓库中来查找jar包。

    • maven用三个向量来组成一个坐标,这个坐标确定唯一的依赖包:

      • groupid:公司或组织域名倒序+项目名
      • artifactid:模块名工程名
      • version:jar包版本
    • maven会根据坐标在仓库中来查找jar包,把三个向量拼接起来就是依赖包的路径。

      • <dependency>
          		<groupId>org.springframework</groupId>
          		<artifactId>spring-core</artifactId>
          		<version>4.3.0.RELEASE</version>
          	</dependency>
        <!--对应的路径转换格式:groupid/artifactid/artifactid+version+.jar -->
        <!--org/springframework/spring-core/spring-core4.3.0.RELEASE  .jar-->
        

    仓库

    在上面提到了坐标,你应该认识到了坐标标识了依赖包的路径,而这个路径是相对于仓库的路径的。为什么需要一个仓库呢?上面说了eclipse实质上也是通过路径来导入依赖包的,如果你没有一个统一的文件夹来管理依赖包的话,零散的依赖包足以让你头疼了。而maven的仓库是一个包含了众多依赖包的仓库,而且maven的依赖管理可以很方便地添加依赖包信息。

    • 仓库的分类
      • 本地仓库:本机上的仓库,通常都会有一个本机仓库,不然你老是需要从远程仓库获取的话就很费时间了;而事实上maven会指定一个默认的本地仓库路径,第一次使用maven的时候,会把maven需要的插件和远程库中存储的jar包下载下来并存储到本地仓库中。
      • 远程仓库:事实上你可以给本地仓库存储你自己的jar包,而某个jar包本地没有的时候,就需要从远程仓库下载下来。
        • 私服仓库:是一个远程仓库,但距离比较近,通常是企业中自己内部的maven仓库,通常私服maven仓库都会使用nexus来搭建。
        • 中央仓库:是maven维护的远程仓库,它里面存储的东西比较全。
    • 依赖包的查找顺序:先从本地仓库查找,本地仓库没有就去远程仓库查找(企业中一般是本地仓库->私服仓库->中央仓库)。当查找到了之后,都会下载到本地仓库。【记住初始情况下,maven的仓库是比较干净的,仅仅包含一些基本插件。】
    • 仓库中存储的内容:
      • 插件【maven的功能依赖于插件,没有插件就没有功能,好比电脑需要驱动,maven的构建是通过插件来实现的】
      • jar包
      • 自己开发的maven工程【其实你应该知道自己是可以把自己的工程打成jar包,然后可以在别的工程中导入这个jar包来使用这个jar包中的类,所以你是可以把自己的类库放到仓库中的


    入门示例

    下面以创建一个maven项目,并使用maven的依赖管理来给项目添加依赖为例:

    创建maven工程:

    关于如何创建一个maven项目,下面以eclipse中的为例,如果你需要idea的,可以点击下面的链接学习。
    图解在IntelliJ IDEA中创建第一个Maven项目

    新建工程->选择maven project

    添加依赖

    在pom.xml中添加下列代码:

    	<dependencies>
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>javax.servlet-api</artifactId>
    			<version>3.1.0</version>
    			<scope>provided</scope>
    		</dependency>
    	</dependencies>
    

    可以看得出来,依赖已经导入了我们项目的类库。

    所以我们利用依赖包中的类来编写代码的时候就不会报错了。


    Maven标准目录结构

    maven要依据一定的目录规范来管理项目,所以要想用maven管理项目,要遵循规范。下面会讲一下目录定义规范,这样是面向全手动创建maven项目的时候,在很多时候,都会使用工具来创建,比如eclipse中就可以直接创建一个maven工程,这个工程遵循maven工程的目录规范。

    约定的目录结构

    maven构建一个工程要遵循这个目录规范。

    • 工程目录【下面的缩进程度代表目录级数】
      • src目录:存放工程源码的地方
        • main目录:存放主程序的源代码,这里放的是主体程序代码。
          • java目录:存放java源文件
          • resource目录:存放框架或其他工具的配置文件
          • 【为web项目时会多出一个webapp目录】webapp目录:存放页面素材
        • test目录:存放测试程序的源代码的地方,这里放的都是一些测试用的代码。
          • java目录:存放java源文件
          • resource目录:存放框架或其他工具的配置文件
      • pom.xml文件:这个文件定义了这个maven工程的相关配置。

    补充:

    • maven使用一个pom.xml文件来管理依赖。pom中配置依赖信息和maven的一些配置信息,这会在下面讲解。

    pom配置:

    • pom是Project Object Model项目对象模型的意思。
    • pom.xml是maven工程的核心文件,与构建工程相关的一切配置(依赖信息、插件信息等等)都在这个文件中配置
    • pom.xml中的可配置标签很多,我们这里仅仅介绍经常使用的。这些经常使用的也足够你日常使用了。

    常见标签

    • modelVersion:是pom的版本,一般都是默认生成的,不需要关心
    • groupId:标识当前工程的所属组织,写法类似包名。【为什么工程也有这个呢?因为我们的工程也是能打包到本地仓库的。】
    • artifactId:当前工程的工程名
    • version标签:当前工程的版本号
    • dependencies标签:用于管理这个工程的依赖
      • dependency标签:指定某个依赖的信息
        • groupId:标识依赖包的所属组织,写法类似包名。
        • artifactId:依赖包的包名。
        • version:依赖包的版本。
        • scope标签:依赖包的依赖范围。

    依赖级别依赖范围

    依赖信息中的scope标签是用来定义依赖范围的。依赖范围影响依赖的生存周期(就好比游戏中的特殊状态,可能一些状态可用于pk,一些状态可用于打副本,一些状态可用于任务,不同的地方影响效果是否生效。),依赖范围的值有以下几个:

    • compile:编译级别的依赖会用在编译、测试、运行的过程中。默认依赖范围:compile
    • test:test仅仅针对test目录下的源文件,由于test目录下存放的是test文件,测试文件一般都不会编译到主程序中,所以test级别的依赖是不会在编译和运行中生效的。只在测试编译和测试运行阶段可用。这个级别的依赖包例如有junit包,junit仅仅用来测试,在主程序编译和运行中是不需要它的。
    • provided:provided代表已提供的意思,provided范围会用来编译和测试,不会出现在运行中,provided主要用来处理容器也提供了我们所需要的包的情况。例如servlet-api这种依赖包tomcat容器也会提供给部署的程序,如果提供多个同名的依赖包可能会导致主程序运行出错。
    • runtime:在编译的时候不需要(没有用到具体类),但是在运行和测试的时候需要用到,就可以使用这个。例如数据库驱动包,它仅仅在运行和测试的时候会使用到这个依赖包。
    • system:类似provided,对于编译和测试有效,运行时不需要,不建议使用,所以不讲

    依赖传递的导入

    要注意,在一个工程中,如果导入的依赖需要一系列依赖(A包需要B包才能正常,那么也会导入B包),那么也会导入这一些依赖,例如struts2-core依赖一系列的包。

    演示:基于eclipse

    仅仅导入struts2-core的时候,maven会自动导入struts2-core所依赖的包:

    发现maven自动导入了struts2-core依赖的包(这些依赖包是由struts2-core项目中的pom.xml指定的)

    依赖传递问题

    • 依赖传递的过程中:
      • 路径最短者优先
        • A依赖B,B依赖C,C依赖D(版本1.1)
        • A依赖E,E依赖D(版本1.2)
        • 导入时选择版本D(版本1.2)
      • 路径相同,先声明者优先【意思是如果A同时依赖于B和C,而B和C都含有同一个依赖包P,如果在A的继承声明中先声明B,那么A会继承B的依赖包P,所以P版本取决于B】

    依赖排除

    可能会遇到一种情况,在同一个工程中,A包依赖B包的1.0版本,C包依赖B包的1.5版本。那么B的1.0和1.5都被引入了。这可能会导致紊乱,因为构建的时候会不清楚使用哪个版本的B依赖包。这时候我们需要使用依赖排除来解决这个问题。【一般都是排除低版本】

    例如struts2-core依赖javassist包,hibernate-core也依赖javassist包,根据依赖的依赖的导入规则,这时候会有两个javassist

    为了避免紊乱,我们要使用exclusions排除。在eclipse中,我们可以在Dependency Hierarchy中右键选中包进行排除,也可以使用以下xml式排除:

      	<dependency>
      		<groupId>org.apache.struts</groupId>
      		<artifactId>struts2-core</artifactId>
      		<version>2.3.34</version>
      		<exclusions>
                <!-- 排除struts2-core的依赖中的javassist依赖 -->
      			<exclusion>
      				<groupId>javassist</groupId>
      				<artifactId>javassist</artifactId>
      			</exclusion>
      		</exclusions>
      	</dependency>
    

    依赖的继承

    在建立多个有继承关系的工程时,父工程的依赖信息会传递给子工程。
    在父工程中声明了依赖后,就算子工程没有声明,也会传递到子工程中

    版本锁定

    在分模块开发时,多个子模块可能会使用上同一个依赖包,那么如何限定多个子模块都使用同一版本的依赖包呢?可以使用版本锁定。

    • 在父工程使用dependencyManagement来管理依赖(dependencyManagement不会导入依赖),那么依赖的版本会被父工程锁定。
    • 通常情况下,父工程的依赖会传递给子工程(如果你另外也使用了dependencies标签来声明依赖),那么子工程不声明的时候是没问题的;如果子工程显式导入被锁定版本的依赖时,会报错,会提示版本被父工程锁定。
    <dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>junit</groupId>
    				<artifactId>junit</artifactId>
    				<version>4.9</version>
    				<scope>test</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    

    统一管理依赖版本:

    你应该经常见到某个框架的依赖包都是同一版本的,如果我们将这些依赖信息都添加到pom.xml中,可能会出现多个重复的version标签,如果你要修改的话是很麻烦的,要逐个逐个去修改版本。

    事实上,是可以统一管理依赖版本的,同一管理依赖版本之后,如果我们要修改这个框架下的包的版本,那么只需要修改一处就行了。

    • 使用properties内使用自定义标签统一版本号,自定义标签相当于一个变量,后面的version那里可以引用这个变量。
     <properties>
         <!-- 使用自定义标签统一版本号,标签名是自定义的 -->
      	<struts2-version>2.3.34</struts2-version>
      </properties>
      
      <dependencies>
      	<dependency>
      		<groupId>org.apache.struts</groupId>
      		<artifactId>struts2-core</artifactId>
            <!--在version标签中引用 -->
      		<version>${struts2-version}</version>
      	</dependency>
      </dependencies>
    

    注意:properties标签并不是只能用于统一声明依赖版本,但凡是需要统一声明的地方都可以考虑使用properties标签。



    Maven命令

    全局命令

    • maven -v :查看版本

    工程级命令

    以下命令针对于maven工程,必须到pom.xml目录才能执行命令

    • mvn clean:清理之前编译出的class文件,相当于清理target目录及其目录下的所有文件。
    • mvn compile:编译主程序,效果是把src/main/java下的java源文件编译为class文件并输出到target下的classes目录下。
    • mvn test-compile:编译测试程序
    • mvn test:执行src/test/java下的单元测试类,会打印出测试结果(如果被junit标识成测试类的话),并把src/main/java下的java源文件编译为class文件并输出到target下的test-classes目录下。
    • mvn package:打包,java项目打包成jar包,web项目打包成war包。打包的文件存储到target目录下。
    • mvn install:安装,把maven工程打包成jar包或war包并保存到本地仓库中。【在本地仓库目录下根据坐标来生成包路径来保存】。对于我们自己的maven工程,可以使用mvn install把它安装到仓库中。

    命令生命周期

    • 属于同一个生命周期的指令,当后面的命令执行时,前面的命令也会自动执行。
    • 常见命令周期:
      • clean :在进行真正构建之前的一些清理工作。
        • 包含命令:pre-clean,clean,post-clean
      • default:构建的核心部分:编译、测试、打包、部署等等。【要注意,大部分命令都处于default生命周期,所以执行某个命令时,生命周期前面的命令也会自动执行。】
        • 包含命令:validate,compile,test,package,verify,install,deploy....
      • site:生成项目报告、站点、发布站点。。
        • 包含命令:pre-site,site,post-site,site-deploy

    每一个阶段都有一个对应的命令,且有相应的插件来支持命令的运行。


    setting.xml配置文件

    仓库配置

    本地仓库配置

    maven安装路径下confsettings.xml文件,在settings.xml中配置localResposity标签。,它是被注释了的,有配置方法的提示。

    默认目录:用户目录下.m2/repository

    添加远程仓库

    <mirrors>
    	<!-- 中央仓库1 -->
            <mirror>
                <id>repo1</id>
                <mirrorOf>central</mirrorOf>
                <name>Human Readable Name for this Mirror.</name>
                <url>http://repo1.maven.org/maven2/</url>
            </mirror>
    
            <!-- 中央仓库2 -->
            <mirror>
                <id>repo2</id>
                <mirrorOf>central</mirrorOf>
                <name>Human Readable Name for this Mirror.</name>
                <url>http://repo2.maven.org/maven2/</url>
            </mirror>
    </mirrors>
            
    

    Eclipse中使用maven

    配置maven

    eclipse有自带的maven插件,但不建议使用。

    把独立的maven添加成一个新的maven:

    配置user settings:

    创建maven工程:

    【maven model用于分模块开发时创建子工程,多个子工程与核心工程组成一个完整的项目。】

    新建工程->选择maven project

    下面给的是打包方式为war的时候的目录结构:

    修改JRE版本:

    默认情况下,maven工程引用的jre库是1.5的,这可能会导致一些语法问题(例如泛型的语法问题),所以通常需要更改这个引用的jre库版本。

    • 修改方法:在setting.xml中修改profiles标签
    <profile>
    			<id>jdk18</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>
    				<maven.compiler.encoding>utf-8</maven.compiler.encoding>
    			</properties>
    </profile>
    

    导入依赖

    • 方式一:手动添加,通过手动拷贝等方式统一增加。可以百度包名+maven来查找依赖信息的写法,拷贝下来粘贴到pom.xml中即可。

      • <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        
    • 方式二:在eclipse,双击打开pom.xml,默认情况下不是xml界面,点击下面的dependencies选项,再点击add,在中间的搜索框输入信息搜索依赖,选择依赖包,最后点击确认。这要求你比较熟悉需要哪些包。

    1539015718240

    1539015941160

    添加插件

    有时候我们希望给maven工程添加额外的插件,例如tomcat7:run插件,这个插件能使得我们的工程虚拟地部署到tomcat中。

    • mvn tomcat:run 命令是一个插件,需要添加才能执行这条命令,添加方式:项目右键选择maven,再add plugin,然后搜索tomcat

      • <!--build与dependencies是同一级的 -->
        <build>
          	<plugins>
          		<plugin>
          			<groupId>org.apache.tomcat.maven</groupId>
          			<artifactId>tomcat7-maven-plugin</artifactId>
          			<version>2.2</version>
          		</plugin>
                <configuration>
        		<!-- 端口 -->
        		<port>8080</port>
        		<!-- 访问路径 -->
        		<path>/helloworld</path>
        		<!-- 编码 -->
        		<uriEncoding>utf-8</uriEncoding>
        	</configuration>
          	</plugins>
        </build>
        

    这里仅仅给一个添加插件的示例,其他的插件有兴趣可以自查。

    Eclipse中执行maven命令

    工程右键->run as ->第一个maven build可以让你选择之前执行过的命令来执行,第二个maven build可以让你输入指定命令来执行(在goals中输入命令,mvn test只需要输入test即可);至于后面的clean,install和test的意思已经显而易见了。

    创建web工程

    如果想创建一个web工程,需要在创建工程的时候打包方式改成war。但默认情况下src/main下是没有webapp目录(存放WEB-INF目录和web.xml的目录)的。

    • 生成webapp目录:
      • 方式一: WEB-INF目录和web.xml,javaEE tools->Generate Deploy...
      • 方式二:手动创建目录和文件

    依赖范围冲突问题:

    什么是依赖范围冲突呢?这涉及到依赖范围问题,主要是provided问题。以servlet-api依赖为例,这个依赖tomcat会提供给我们部署的项目,但如果我们添加这个依赖的时候选择了compile,那么这个依赖也会带到部署的项目中,使得存在了两个servlet-api依赖。

    解决方法:这时候要修改servlet-api依赖的范围,改成provided。

    依赖排除问题:

    这个在pom配置的依赖排除中讲过了。这里只提一下,不再演示。

    如何运行项目

    java项目:

    • 运行方式一:项目右键->run as->java application
    • 由于方式二跟直接到目标目录执行java没什么区别,所以这里不讲,有兴趣可以自查mvn exec

    web项目:

    • 部署方式一:在添加了插件之后,使用tomcat插件部署:mvn tomcat7:run
      • 选择5 Maven build之后,输入命令tomcat7:run
      • 区别:插件的是虚拟环境,会比较快。
    • 部署方式二:打成war包之后,把war包拷贝到tomcat目录中。
    • 部署方式三:建立服务器之后,把项目添加到tomcat中;或者在pom.xml文件点击右键,直接把项目添加到tomcat中。

    工程拆分和聚合

    • 在一个比较大的项目开发协作中,如果按照以前的开发的话,是一个工程。这样会有一些问题。拆分、分模块便于测试和开发。不同开发者仅仅面向自己的工程。
    • 然后在整合的时候,把工程聚合起来,就能聚合成一个完整的项目了。

    工程的拆分

    工程的拆分是创建一个核心父工程,然后创建多个子模块的情况。核心父工程一般不会编写什么内容,一般只作为依赖的汇总(让父工程引入共有依赖,子工程单独依赖的单独引入)。

    创建父工程:

    创建子工程

    为了让父工程能管理到子工程,所以在父工程下右键"new-->maven module"

    创建完父工程和子模块后,可以在父工程的pom.xml中看到父工程管理到了子模块:

    而子模块也指向了父工程:

    然后子模块怎么开发呢?它相当于与一个独立的模块,所以你可以像往常一样开发。不过提一下的是,可能会发生service层调用dao层,那么这怎么实现呢?这就需要我们在service层中添加dao层的依赖了,这样service层就可以调用dao层的方法了。

    这里提一下工程拆分与框架整合的问题,在以前一个工程中,dao和service都是交给spring去管理的,那么现在
    该怎么处理呢?首先,要注意的是,只要我们配置了spring(这里注意,依赖已经导入了),无论是xml还是注解
    式,那么spring就能够管理好我们的bean。所以,我们现在其实只需要关心我们的bean是否交给了spring来管理
    即可。而这个单个模块的测试可以在test目录下再编写代码来测试。

    工程的聚合

    拆分工程之后,开发完成了,怎么聚合使用呢?
    首先,要注意父工程管理着子模块,

    如果打包父工程,那么子工程也会进行打包。

    而通常我们在进行web开发的时候,由于子模块web是核心项目,而子模块web又依赖着子模块service,而在打包的时候依赖的包也会打成jar包,所以打包子模块web的时候,web工程的lib里面是有依赖的兄弟工程的,所以我们可以直接运行web工程即可。【这是运行war包的情况】

    我们也可以选择在IDE中直接运行子模块web(在eclipse直接run as),也是能够调用到其他兄弟模块的功能的。


    写在最后

    这篇关于maven的博文看完了,你应该能对maven的使用有一个基本的了解。

    这里给一个常用的查maven的依赖信息的网站:mvnrepository.com


  • 相关阅读:
    Codeforces Round #615 (Div. 3)
    「网络流 24 题」最长 k 可重区间集
    「网络流 24 题」方格取数
    「网络流 24 题」试题库
    debian服务sh启动java,设置开机启动
    debian重置root密码
    uwsgi加载ini文件,nginx重新加载,查看配置文件路劲
    pptpd启动
    android studio java lib不能直接运行
    clipChildren是否限制子控件在该容器所在的范围内
  • 原文地址:https://www.cnblogs.com/progor/p/9904072.html
Copyright © 2011-2022 走看看