背景

1.1、

  • 场景

  假如你正在Eclipse下开发两个Java项目,姑且把它们称为A、B,其中A项目中的一些功能依赖于B项目中的某些类,那么如何维系这种依赖关系的呢?

很简单,这不就是跟我们之前写程序时一样吗,需要用哪个项目中的哪些类,也就是用别人写好了的功能代码,导入jar包即可。所以这里也如此,可以将B项目打成jar包,然后在A项目的Library下导入B的jar文件,这样,A项目就可以调用B项目中的某些类了。

  • 缺陷

  如果在开发过程中,发现B中的bug,则必须将B项目修改好,并重新将B打包并对A项目进行重编译操作在完成A项目的开发后,为了保证A的正常运行,就需要依赖B(就像在使用某个jar包时必须依赖另外一个jar一样),两种解决方案,第一种,选择将B打包入A中,第二种,将B也发布出去,等别人需要用A时,告诉开发者,想要用A就必须在导入Bjar包。两个都很麻烦,前者可能造成资源的浪费(比如,开发者可能正在开发依赖B的其它项目,B已经存储到本地了,在导入A的jar包的话,就有了两个B的jar),后者是我们常遇到的,找各种jar包,非常麻烦(有了maven就不一样了)

1.2、

  • 场景

  我们开发一个项目,或者做一个小demo,比如用SSH框架

  • 缺陷

  那么我们就必须将SSH框架所用的几十个依赖的jar包依次找出来并手动导入,超级繁琐。 

定义

  • 官方

  Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具。

  通俗

  通过pom.xml文件的配置获取jar包,而不用手动去添加jar包。

详解

以pom.xml获取junit的jar包的编写为例

加入上面的pom.xml文件属于A项目,那么A项目肯定是一个maven项目,通过上面这三个属性能够找到junit对应版本的jar包,那么junit项目肯定也是一个maven项目,junit的maven项目中的pom.xml文件就会有三个标识符,比如像下图这样,然后别的maven项目就能通过这三个属性来找到junit项目的jar包了。所以,在每个创建的maven项目时都会要求写上这三个属性值的。

          

maven的安装

    这一步maven环境的配置,我觉得有必要安装一下,目的为了使用命令行创建maven项目,和使用命令行操作maven项目。这里不细讲,给出链接,跟安装jdk环境类似,maven的安装教程和配置。还有注意,我以下用的是maven3.0.4版本(比较低的),你们可以下载最新的版本,最好是使用jdk1.7.

仓库的概念

   通过pom.xml中的配置,就能够获取到想要的jar包(还没讲解如何配置先需要了解一下仓库的概念),但是这些jar是在哪里呢?就是我们从哪里获取到的这些jar包?答案就是仓库。仓库分为:本地仓库、第三方仓库(私服)、中央仓库。

  • 本地仓库

Maven会将工程中依赖的构件(Jar包)从远程下载到本机一个目录下管理,每个电脑默认的仓库是在 $user.home/.m2/repository下,例如我的就在:C:\Users\Administrator\.m2\repository

  

              

  一般我们会修改本地仓库位置,自己创建一个文件夹,在从网上下载一个拥有相对完整的所有jar包的结合,都丢到本地仓库中,然后每次写项目,直接从本地仓库里拿就行了

   这里面有很多各种各样我们需要的jar包。

   修改本地库位置:在$MAVEN_HOME/conf/setting.xml文件中修改,

                

   

    D:\java\maven\repository:就是我们自己创建的本地仓库,将网上下载的所有jar包,都丢到该目录下,我们就可以直接通过maven的pom.xml文件直接拿。

  •   第三方仓库

  第三方仓库,又称为内部中心仓库,也称为私服

  私服:一般是由公司自己设立的,只为本公司内部共享使用。它既可以作为公司内部构件协作和存档,也可作为公用类库镜像缓存,减少在外部访问和下载的频率。(使用私服为了减少对中央仓库的访问

  私服可以使用的是局域网,中央仓库必须使用外网

  也就是一般公司都会创建这种第三方仓库,保证项目开发时,项目所需用的jar都从该仓库中拿,每个人的版本就都一样。

  注意:连接私服,需要单独配置。如果没有配置私服,默认不使用

  •   中央仓库

  Maven内置了远程公用仓库:http://repo1.maven.org/maven2

  这个公共仓库是由Maven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。目前是以java为主

  工程依赖的jar包如果本地仓库没有,默认从中央仓库下载

命令

  命令操作maven java或web项目

  • 编译:mvn compile    --src/main/java目录java源码编译生成class (target目录下)
  • 测试:mvn test      --src/test/java 目录编译
  • 打包:mvn package   --生成压缩文件:java项目#jar包;web项目#war包,也是放在target目录下
  • 清理:mvn clean      --删除target目录,也就是将class文件等删除
  • 安装:mvn install     --将压缩文件(jar或者war)上传到本地仓库
  • 部署|发布:mvn deploy   --将压缩文件上传私服
  • 常用:mvn clean install

  其他命令

  • mvn eclipse:eclipse      maven的java或web项目转换Eclipse工程
  • mvn eclipse:clean   清除eclipse设置信息,又从eclipse工程转换为maven原生项目了    
  • mvn idea:idea    maven的java或web项目转换IDEA工程
  • mvn idea:clean     清除idea设置信息,又从idea工程转换为maven原生项目了

使用Myeclipse创建maven自定义项目

使用myeclpse创建项目前,需要在myeclipse中配置maven的一些信息,比如:配置本地仓库、安装自定义maven(myeclipse中高版本自带了maven)等,这里省略。

1、java项目

  • 选择maven project,如果右键新建没有,通过other获得

   

  • 创建一个简单项目(跳过骨架选择)

   

  • 设置项目参数,创建java项目

   

   

  • 创建java项目结果

  

2、创建maven web项目

  • 同上
  • 同上
  • 设置项目参数,其他一样,选择打包方式不一样。

  

  • 创建web项目结果

   

  • 可能报错1:pom.xml报错

   

结果如下

       

然后需要更新一下项目,就不报错了。

  

  • 报错2,编写jsp时报错

      

错误信息为缺少serlvet-jar和jsp-jar包

    

解决:使用pom.xml定位导入相应的jar包

       

找到jsp-jar包,scope的作用是表示该jar包的作用范围,provided表示在编译和测试期有效,在运行期则无效。具体后面讲解pom.xml时会讲解到。     

   

找到servle-jar包

   

pom.xml中检查,修改

   

修改完后,发现两个jar包都加载进来了,项目完好,不在报错了。

    

3、创建maven项目

  都一样,在项目参数那里修改即可

   

  结果

  

  maven项目一般没用,在开发中将一个项目拆分成多个项,就需要使用maven项目(pom项目)将其他子项目进行整合,下一章节讲解,很重要。很重要。

4、myeclipse maven操作

      

   6--9 都是快捷方式

   9 测试,相当于命令行 mvn test

   8 安装,相当于命令行 mvn install  作用:将其上传到本地仓库,具体见上面讲解

   7 关联源码,这个不需要解释吧,平常我们使用别的jar包也关联过源码

   6 清理,mvn clean

   5 maven bulid  执行maven命令,等效 mvn

   

   4 maven build  5快速的操作,如果没有操作过,与5相同,如果操作过一次,将直接执行上一次5的命令,如果操作多次,将提供选择框

5、例子,将maven web项目发布到tomcat运行

   命令:tomcat:run

   

   通过网址即可访问,同时会将该项目上传到本地仓库。

pom.xml的依赖关系

1、如何获取坐标(也就是三个关键属性值)

方式1:使用网站搜索[从中央仓库拿]

  • 步骤一:百度搜索关键字

  

  • 步骤二:输入关键字查询获得需要内容,确定需要版本

  

        

  • 步骤三、获得坐标

  

方式2、使用本地仓库,通过myeclipse获得坐标

  上面已经介绍过了如何从本地仓库获取对应jar,这里在简单阐述一下

  • 步骤一:添加依赖,pom.xml文件中,右键  

    

  • 步骤二:获得坐标

   

依赖的常见配置

  为了避免不知道说的哪些配置属性,看下面图就明白了,就是dependency下的属性配置,全部有9个,讲其中的7个。

   

  groupId、artifactId、version是依赖的基本坐标,缺一不可,这三个可以不用将,都知道,重要的是除了这三个之外的配置属性需要我们理解

  • type:依赖的类型,比如是jar包还是war包等,默认为jar,表示依赖的jar包

  注意:<type>pom.lastUpdated</type> 这个我们在上面添加servlet-jar的时候就遇到过,看到lastUpdated的意思是表示使用更新描述信息,占位符作用,通俗点讲,选择该类型,jar包不会被加载进来,只是将该jar包的一些描述信息加载进来,使别的jar包在引用他时,能够看到一些相关的提示信息,仅此而已,所以说他是个占位符,只要记住他的jar包不会被加载进来。

  • optional:标记依赖是否可选。默认值false

  比如struts2中内置了log4j这个记录日志的功能,就是将log4j内嵌入struts2的jar包中,而struts2有没有log4j这个东西都没关系,有它,提示的信息更多,没它,也能够运行,只是提示的信息就相对而言少一些,所以这个时候,就可以对它进行可选操作,想要它就要,不想要,就设置为false。

  • exclusions:排除传递依赖,解决jar冲突问题

  依赖传递的意思就是,A项目 依赖 B项目,B项目 依赖 C项目,当使用A项目时,就会把B也给加载进来,这是传递依赖,依次类推,C也会因此给加载进来。这个有依赖传递有好处,也有坏处,坏处就是jar包的冲突问题,比如,A 依赖 B(B的版本为1),C 依赖 B(B的版本为2),如果一个项目同时需要A和C,那么A,C都会传递依赖将B给加载进来,问题就在这里,两个B的版本不一样,将两个都加载进去就会引起冲突,这时候就需要使用exclusions这个属性配置了。maven也会有一个机制避免两个都加载进去,maven 默认配置在前面的优先使用,但是我们还是需要使用exclusions来配置更合理,这里使用spring bean 和 struts2 spring plugin 来举例子说明这个问题并使用exclusions解决这个问题。(spring bean 和 struts2 spring plugin都需要依赖spring-core,但版本不一样)

  从本地仓库中找到这两个jar包

  

  maven自己的解决方案如下,maven 默认配置在前面的优先使用,具体如下

  先将spring-beans加载进去的,所以会将spring-beans依赖的spring-core的版本加载进来。

        

  先将struts2-spring-plugin加载进来,那么就会将其依赖的spring-core的版本加载进来

   

  使用exclusions来配置,即使struts2-spring-plugin 配置在前面,也需要使用3.2.0版本。则需要为struts2-spring-plugin 排除依赖(不使用3.0.5依赖)

   

  注意:这样,就将struts2-spring-plugin依赖的spring-core的版本排除依赖了,也就是该依赖的spring-core不会在加载进来,查看代码,看是否符合要求,如果不符合要求,需要手动的修改 

  

  • scope:依赖范围,意思就是通过pom.xml加载进来的jar包,来什么范围内使用生效,范围包括编译时,运行时,测试时

  

  compile:默认值,如果选择此值,表示编译、测试和运行都使用当前jar

  test:表示只在测试时当前jar生效,在别的范围内就不能使用该jar包。例如:junit 。此处不写也不报错,因为默认是compile,compile包扩了测试

  runtime,表示测试和运行时使用当前jar,编译时不用该jar包。例如:JDBC驱动。JDBC驱动,在编译时(也就是我们写代码的时候都是采用接口编程,压根就没使用到JDBC驱动包内任何东西,只有在运行时才用的到,所以这个是典型的使用runtime这个值的例子),此处不写也不报错,理由同上

  provided,表示编译和测试时使用当前jar,运行时不在使用该jar了。例如:servlet-api、jsp-api等。【必须填写】什么意思呢? 在我们以前创建web工程,编写servlet或者jsp时,就没导入过jar包把,因为myeclipse或者别的ide帮我们提供了这两个jar包,内置了,所以我们在编译期测试期使用servlet都不会报缺少jar包的错误,而在运行时期,离开了myeclipse或别的ide,就相当于缺失了这两个jar包,但此时tomcat又会帮我们提供这两个jar,以便我们不会报错,所以,这两个很特殊。看图

  1、开发阶段(MyEclipse提供),看下图以此证明我们说的

  java web 5.0项目: 

  java web 6.0项目:

  2、运行阶段(tomcat提供)   

  

  所以,根据这个特点,如果使用maven开发项目,就不是web项目了,那么myeclipse就不会在给我们提供这两个jar包,我们就必须自己手动通过坐标从仓库中获取,但是针对上面的分析,当运行的时候,tomcat会帮我们提供这两个jar包,所以我们自己从仓库中获取的jar包就不能和tomcat中的冲突,那么就正好可以通过provided这个属性,来设置这两个jar的作用范围,就是在变异时期和测试时期生效即可。

  这个例子就可以解释上面创建maven web时产生的错误和解决方案了。

  system:表示我们自己手动加入的jar包,不属于maven仓库(本地,第三方等),属于别得类库的这样的jar包,只在编译和测试期生效,运行时无效。一般不用                    

依赖调节原则

这个就是maven解决传递依赖时jar包冲突问题的方法,按照两种原则,上面已经介绍了一种了,就是下面的第二原则

  • 第一原则:路径近者优先原则

A-->B-->C-->D-->X(1.6)

E-->D-->X(2.0)

使用X(2.0),因为其路径更近 

  • 第二原则:第一声明者优先原则。就是如果路径相同,maven 默认配置在前面的优先使用

A-->B --> X(1.6)

C-->D--> X(2.0)

这样就是路径相同,那么如果A在前面,C在后面,则使用X(1.6),maven会先根据第一原则进行选择,第一原则不成,则按第二原则处理。

最新文章

  1. 20个不可思议的 WebGL 示例和演示
  2. AOJ DSL_2_A Range Minimum Query (RMQ)
  3. A与B相交后的图形查询
  4. tomcat 性能优化
  5. TW2015技术雷达中文版发布
  6. Yii2框架打包成Phar包报错的经历
  7. TreodeDB测试及总结
  8. android144 360 快捷方式
  9. 手机web开发
  10. PageMapAdapter MapAdapter (续webServices)
  11. mysql的函数
  12. awk命令练习
  13. jdk源码阅读笔记-Integer
  14. Python 爬虫 当当网图书 scrapy
  15. 【VBA】数组定义时,括号内的数值n为最大下标,其长度为n+1
  16. C# DGVPrinter.cs 打印方法
  17. IQueryable 与 IEnumberable 接口的区别
  18. redis管道技术
  19. hivepython 实现一行转多行
  20. outline的兼容性及使用限制

热门文章

  1. vue 后退不刷新,前进刷新 keep-alive
  2. 编译vim8
  3. 单例模式(Singleton)---创建型
  4. Luogu P5022 旅行 搜索+贪心
  5. 弱势图解AC自动机
  6. O(1)快速乘与O(log)快速乘
  7. delphi将两个Strlist合并,求并集
  8. JavaWeb_(Mybatis框架)Mapper动态代理开发_三
  9. spring事务之事务传播机制和隔离级别
  10. 1.3 JAVA规范以及基础语法(if条件和循环)