在学习Spring框架的过程中,要导入很多jar包,不但非常麻烦,初学时还很容易忘记要用哪些jar包,尤其是有依赖关系的jar包。偶然看到有使用maven构建web项目的方法,可以非常方便的管理jar包还可以,就深入研究了一下。
一、jar包的导入引发的问题
在学习使用框架的时候,要先导入一些jar包,比如:spring-webmvc-4.1.5.RELEASE.jar。
使用SSM框架时要导入十几个jar包,需要手动一个一个导入,非常繁琐,还容易遗忘有依赖关系的一些jar包,(比如,要使用A包,A依赖于B,C,D,要使用A,就要先导入B,C,D,有些依赖容易忘记,有些依赖可能根本不知道)。
为了解决这种依赖关系,可以使用maven来构建和管理项目。
二、maven是什么?
maven是工具,是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具。
我认为maven的核心功能是合理描述项目间的依赖关系,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包,如果需要使用pom.xml来获取jar包,那么首先该项目就必须为maven项目,maven项就是在java项目和web项目的上面包了一层maven,本质上java项目还是java项目,web项目还是web项目,但是包了maven之后,就可以使用maven提供的一些功能了(比如:通过pom.xml添加jar包)。
三、maven的安装
(一),手动安装maven
-
从官网下载,并解压到一个目录。
-
配置环境变量,打开系统环境变量新建一个M2_HOME将解压后的maven存放路径放在此,然后在path路径加入
mvn.pngM2_HOME\bin
路径
在mac中加入~/.bash_profile中
-
输入mvn-v检测是否安装成功
mvn-v.png
- 复制
M2_HOME/conf/setting.xml
文件到$user.home/.m2/setting.xml
,这样用户每次升级后就不要在次修改setting.xml文件了。如果不设置setting.xml,就会按照默认的设置执行。根目录下的设置是全局的,用户目录下的设置只对当前用户起作用。
(二),高版本的Eclipse,MyEclipse中已集成了maven,可以直接使用。
MyEclipseMaven.png
设置maven为自己安装的版本
MyEclipseMaven2.png
这两种方式的区别是,自己安装的可以自己设置配置文件,并使用命令行来管理项目,而集成的配置是默认好的,且使用不了命令行。
四、仓库的概念
通过pom.xml中的配置,就能够获取到想要的jar包,但是这些jar是在哪里呢?我们从哪里获取到的这些jar包?答案是仓库。
仓库分为:本地仓库、第三方仓库(私服)、中央仓库
- 本地仓库,Maven会将工程中依赖的构件(Jar包)从远程下载到本机一个目录下管理,每个电脑默认的仓库是在 $user.home/.m2/repository下
- 第三方仓库,又称为内部中心仓库,也称为私服。一般是由公司自己设立的,只为本公司内部共享使用。它既可以作为公司内部构件协作和存档,也可作为公用类库镜像缓存,减少在外部访问和下载的频率。(使用私服为了减少对中央仓库的访问)。注意:连接私服,需要单独配置。如果没有配置私服,默认不使用
- 中央仓库,Maven内置了远程公用仓库:
http://repo1.maven.org/maven2
。这个公共仓库是由Maven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。目前是以java为主,工程依赖的jar包如果本地仓库没有,默认从中央仓库下载。
五、在MyEclipse中使用maven创建web项目
步骤
-
右键,new maven project
new1.png
-
选中Create a simple project
new2.png
-
填写项目名
new3.png
或者选择用模板创建项目
-
不选Create a simple project,直接下一步,在弹出的对话框中选择类型
new4.png
-
填写项目名
new5.png
创建完项目后,有几点要注意:
-
更改jre版本
new6.png
-
如果是使用simple project创建项目,则需要生成web.xml文件(使用模板创建的项目会自动生成)
new7.png
项目结构如下
structure.png此时正常部署项目到服务器,并运行:
run.png
可能出现的问题
1)创建maven project时提示内存不足,要修改MyEclipse安装目录下的eclispe.ini 文件,把内存分配修改一下(如:1024m改成2048m)
err.png q_0.png
2)pom.xml文件报错: Cannot detect Web Project version,
q_1.png
这是因为simple project 要指定编译war的版本,在pom.xml中加入以下代码:
q_2.png
在这里指定JRE版本是因为,使用maven update项目时,会在配置文件中查找版本号,默认的是1.5,如果你用的是1.7或1.8,没有在这里写明,就会update 项目后变成1.5而导致其他问题。
3)jsp报错,The superclass "javax,servlet.http.HttpServlet" was not found on the Java Build Path
q_3.png
在pom.xml添加依赖:
q_3_.png
4)导入maven项目时,Referenced file contains errors,这个错一般发生在导入maven项目时,
q_4.png
这时,只需update project即可:
q_4_.png
5)Cannot upgrade/downgrade to Dynamic Web Module 3.0 facet.
q_5.png
解决这个问题要更改一下web.xml中的版本约束:
q_6.png
6)WEB-INF文件夹下lib中没有jar包的问题:
maven用dependency来引用仓库中的jar包,所以,在lib文件夹下是没有jar包的,如果,我想引用自己写的一个jar包,就可以放在lib下,在部署到服务器时,会一同部署过去:
new8.png
六、pom.xml的依赖关系
在pom.xml中添加dependency即可引入jar包
depen.png
比如:我想添加spring-webmvc的jar包到项目中,可以在mavenRepository中央仓库中查找到相应的版本,把代码直接拷贝到pom.xml中即可:
dependency有9个属性,或子节点
dependele.png
-
groupId ---> 组名,一般是反向域名,基本属性,不可少
-
artifactId ---> 项目名,基本属性,不可少
-
version ---> 版本,基本属性,不可少
-
type ---> 依赖的类型,比如是jar包还是war包等,默认为jar
-
classifier ---> 定义构件输出的一些附属构件
-
scope ---> 依赖范围,意思就是通过pom.xml加载进来的jar包,来什么范围内使用生效,范围包括编译时,运行时,测试时。
- compile:默认值,如果选择此值,表示编译、测试和运行都使用当前jar
- test:表示只在测试时当前jar生效,在别的范围内就不能使用该jar包。
- runtime,表示测试和运行时使用当前jar,编译时不用该jar包。例如:JDBC驱动。JDBC驱动,在编译时(也就是我们写代码的时候都是采用接口编程,压根就没使用到JDBC驱动包内任何东西,只有在运行时才用的到,所以这个是典型的使用runtime这个值的例子),此处不写也不报错,理由同上
- provided,表示编译和测试时使用当前jar,运行时不在使用该jar了。例如:servlet-api、jsp-api等。【必须填写】什么意思呢? 在我们以前创建web工程,编写servlet或者jsp时,没导入过jar包,因为myeclipse帮我们提供了这两个jar包,内置了,所以我们在编译期测试期使用servlet都不会报缺少jar包的错误,而在运行时期,离开了myeclipse,就相当于缺失了这两个jar包,但此时tomcat又会帮我们提供这两个jar,以便我们不会报错。如果使用maven开发项目,就不是web项目了,那么myeclipse就不会在给我们提供这两个jar包,我们就必须自己手动通过坐标从仓库中获取,但是针对上面的分析,当运行的时候,tomcat会帮我们提供这两个jar包,所以我们自己从仓库中获取的jar包就不能和tomcat中的冲突,那么就正好可以通过provided这个属性,来设置这两个jar的作用范围,就是在变异时期和测试时期生效即可。
- system:表示我们自己手动加入的jar包,不属于maven仓库(本地,第三方等),属于别得类库的这样的jar包,只在编译和测试期生效,运行时无效。一般不用
-
systemPath ---> 当maven依赖本地而非repository中的jar包,sytemPath指明本地jar包路径
-
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这个属性配置了。 -
optional ---> 标记依赖是否可选。默认值false
依赖调节的两个原则
这个就是maven解决传递依赖时jar包冲突问题的方法:
1、第一原则:路径近者优先原则
A-->B-->C-->D-->X(1.6)
E-->D-->X(2.0)
使用X(2.0),因为其路径更近
2、第二原则:第一声明者优先原则。就是如果路径相同,maven 默认配置在前面的优先使用
A-->B--> X(1.6)
C-->D--> X(2.0)
这样就是路径相同,那么如果A在前面,C在后面,则使用X(1.6)
maven会先根据第一原则进行选择,第一原则不成,则按第二原则处理。
网友评论