一:为什么要使用Maven
1.1:大量的jar包
JavaEE开发领域,需要使用大量的第三方框架和工具jar包,如果每次都进行复制到WEB-INF目录下的lib目录中会导致每次创建一个新的工程就需要将jar包再次复制到lib目录下,从而造成工作区中存在大量重复的文件。
另外,大量的jar包避免不了版本的冲突。
Maven拥有一套完全统一规范的jar包管理体系。可以将每个jar包只在本地仓库中保存一份,项目只需要需要维护一个文本形式的jar包的引用(规范,完整,准确)——我们称之为“坐标”,不仅极大的节约了存储空间,更避免了重复文件太多而造成的混乱。
1.2:jar包之间的依赖关系
jar包往往不是孤立存在的,很多jar包都需要在其他jar包的支持下才能够正常工作;
Maven就可以替我们自动的将当前jar包所依赖的其他所有jar包全部导入进来,无需人工参与。
1.3:Jar包之间的冲突
当一个工程A直接和间接的引用的工程B和C的jar包,但是B和C所用的jar包的版本不一致,此时对于A来说就存在jar依赖冲突。
maven帮我们完美的解决了:
原则:最短路径者优先和先声明者优先
1.4:将项目拆分成多个工程模块
Maven可以实现管理多个工程模块
1.5:实现项目的分布式部署
项目规模增加到一定程度后,可能每个模块都需要运行在独立的服务器上,此时需要maven进行分布式部署
?1.6:小结
- 大量jar包管理
- jar版本依赖冲突
- 管理工程的模块化
- 分布式部署
二:Maven是什么
2.1:自动化构建工具
Maven是一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。
构建工具的演变:Make→Ant→Maven→Gradle→其他……
2.2:构建的概念
构建并不是创建,创建一个工程(只是创建出来了)并不等于构建一个项目。
编写任何Java代码想要执行的话就必须经过编译得到对应的.class文件,才能运行;
当我们需要通过浏览器访问Java程序时就必须将包含Java程序的Web工程编译的结果“拿”到服务器上的指定目录下,并启动服务器才行。这个“拿”的过程我们叫部署。
构建就是以我们编写的Java代码、框架配置文件、国际化等其他资源文件、JSP页面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。
2.3:构建的过程
清理:删除以前的编译结果,为重新编译做好准备。
编译:将Java源程序编译为字节码文件。
测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
报告:在每一次测试后以标准的格式记录和展示测试结果。
打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。
安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。
部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。
?三:?Maven的使用
3.1:Maven的仓库位置
仓库 ?? ??? ?本地库:本地电脑上的某个目录
?? ??? ?远程库: ?? ??? ??? ?1、私服:统一公司、部门、项目组内部人员的jar包 ?? ??? ??? ?2、中央仓库? ? ? ?(位于国外,全世界公用,但是高并发会造成阻塞)? ?? ??? ??? ?3、中央仓库镜像? ?(位于某个地区,一般配置阿里镜像)
注意:?
本地仓库地址默认在C:\Users\Administrator\.m2\repository,但是并不利于开发,因此需要配置本地仓库的路径。
补充:
Java中的VM?options for importer:可以设置导入的VM参数。一般这个都不需要主动改,除非项目真的导入太慢了我们再增大此参数。
Xmx代表程序最大可以从操作系统中获取的内存数量,Xms代表程序启动的时候从操作系统中获取的内存数量。
memory max(Xmx)? ?????????memory start (Xms)
3.2:Maven项目
pom文件pom(Project Object Modle):项目对象模型
?3.3:Maven项目的目录结构
?四:Maven的核心概念
Maven的核心概念包括:POM、约定的目录结构、坐标、依赖、仓库、生命周期、插件和目标、继承、聚合。
4.1 POM
Project?Object Model:项目对象模型。将Java工程的相关信息封装为对象作为便于操作和管理的模型。
4.2 约定的目录结构
约定>配置>编码
4.3 Maven的坐标:
(1)groupId:公司或组织的域名倒序+当前项目名称
(2)artifactId:当前项目的模块名称
(3)version:当前模块的版本
4.4如何通过坐标到仓库中查找jar包?
?<groupId>?</groupId><artifactId></artifactId><version></version>
将三个标签中的值连起来的字符串,找到对应的本地仓库
※注意:
我们自己的Maven工程必须执行安装操作才会进入仓库。安装的命令是:mvn install
任何一个Maven工程会根据坐标到本地仓库中去查找它所依赖的jar包。如果能够找到则可以正常工作,否则就不行。HelloFriend 回到本地仓库去找HelloWorld? jar包。
4.5 依赖管理
当A jar包需要用到B?jar包中的类时,我们就说A对B有依赖。、
直接依赖和间接依赖
如果A依赖B,B依赖C,那么A→B和B→C都是直接依赖,而A→C是间接依赖。
4.5.1 依赖的范围
依赖的范围:类似于变量的作用域,jar包可以使用的范围 ?? ??? ??? ?<scope></scope>指明依赖范围 ?? ??? ??? ??? ?compile: ?? ??? ??? ??? ??? ?默认值,可以使用在main目录与test目录下使用 ?? ??? ??? ??? ??? 部署到Tomcat服务器上运行时要放在WEB-INF的lib目录下 ?? ??? ??? ??? ?test: ?? ??? ??? ??? ??? ?只能在test目录下使用 ?? ??? ??? ??? ??? ?部署时无需上传服务器,服务器上没有是没有问题的 ?? ??? ??? ??? ?provided: ?? ??? ??? ??? ??? ?可以使用在main目录与test目录下使用 ? ?? ??? ??? ??? ??? ?部署时无需上传服务器,因为服务器上理论上时已经存在的了(假定)
4.5.2 依赖的传递性
当存在间接依赖的情况时,主工程对间接依赖的jar可以访问吗?这要看间接依赖的jar包引入时的依赖范围——只有依赖范围为compile时可以访问。
间接依赖是否可以用还需要看依赖的范围,只有是complie才可以间接依赖。
原则:最短路径者优先和先声明者优先
?如果可以不去依赖某个工程的jar包可以使用<exclusion>标签
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
4.5.3?统一管理目标Jar包的版本?
以对Spring的jar包依赖为例:Spring的每一个版本中都包含spring-context,springmvc等jar包。我们应该导入版本一致的Spring?jar包,而不是使用4.0.0的spring-context的同时使用4.1.1的springmvc。
问题是如果我们想要将这些jar包的版本统一升级为4.1.1,显然,我们有统一配置的方式:
?方式:
<properties> ??? <spring.version>4.0.0.RELEASE</spring.version> </properties> ${spring.version}
<properties>
<spring.version>4.0.0.RELEASE</spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
4.6:仓库:
(1)本地仓库:为当前本机电脑上的所有Maven工程服务。
(2)远程仓库
????????a)私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务。
????????b)中央仓库:架设在Internet上,为全世界所有Maven工程服务。
????????c)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
?4.6.3:仓库中的文件
(1)Maven的插件
(2)我们自己开发的项目的模块
(3)第三方框架或工具的jar包
不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
4.7:maven生命周期
Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构建命令了。
- Clean Lifecycle在进行真正的构建之前进行一些清理工作。
- Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署等等。(用的比较多,可以帮助我们自动化构建我们需要的内容)
- Site Lifecycle生成项目报告,站点,发布站点。(在浏览器上查看项目的信息,是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,文档及统计数据自动生成,但是一般我们用不上)
4.7.1:生命周期与自动化构建
运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行mvn install?的时候,代码会被编译,测试,打包。这就是Maven为什么能够自动执行构建过程的各个环节的原因。此外,Maven的插件机制是完全依赖Maven的生命周期的。
4.8:插件和目标
(1)Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
(2)每个插件都能实现多个功能,每个功能就是一个插件目标。
(3)Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如:compile就是插件maven-compiler-plugin的一个功能;pre-clean是插件maven-clean-plugin的一个目标。
五:继承与聚合
5.1:为什么需要继承机制?
由于非compile范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。
父项目一般不做业务处理,所以无需打包,并且无需保留src目录
需要在父项目中声明标签<packaging></packaging> 可以传的值有:
????????pom:不打包 ?? ??? ?jar:默认值,打包时打成jar包 ?? ??? ?war:打包时打成war包
子项目应该声明代码知道父项目是谁
<relativePath>../Parent/pom.xml</relativePath>
<parent>
<groupId>com.atguigu.parent</groupId>
<artifactId>Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 指定父项目pom.xml文件位置 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
5.2:父项目的导包方式:
方式一:
?结果:子项目中直接拥有父项目中的所有jar包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
方式二:
结果:父项目中实际上没有导包进入,只不过进行了声明,子项目需要再次导入声明,但是此时无需指定版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
原因:父项目作为整个项目的管理者,没有业务逻辑代码,所以本身不需要导包,父项目只不过作为jar包管理,这里可能有很多的jar包,子项目中可以根据需求进行声明。
5.3:聚合:
5.3.1:为什么要使用聚合?
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作,方便管理。
5.3.2:配置:
(在父项目中进行配置,目的是父亲知道谁是它的儿子,这样的话才能统一管理子项目)
<modules>
<module>../BoyFriend</module>
<module>../GrilFriend</module>
</modules>
5.3.3:开发中的使用:
1、不拆分模块(项目比较小) ?? ??? ?没有工作空间的概念,项目分开管理 ?? ?2、拆分模块(项目比较大)?? ? ?? ??? ?创建就指定了父子关系,代码自动完善
|