Maven 学习笔记
01 项目的架构
浏览器 -> 视图层 + 控制层 -> 业务逻辑层 -> 持久化层 -> DB
02 目前架构存在的问题 & maven 如何解决这些问题
-
一个项目就是一个工程
如果项目庞大,不适合用package
最好一个模块一个工程,利于分工maven可以将一个工程区分成多个
-
需要的jar包要手动复制、粘贴到web-inf/lib目录下
同样的jar包重复出现在不同工程中,浪费存储空间Maven将jar包存在“仓库”中,有需要使用的工程“引用”接口,不需要复制
-
jar包需要准备或者官网下载
不同技术的官网提供jar包下载的形式是不同的
有些技术的官网就是通过maven SVN等专门工具提供下载的
其中的内容可能不规范maven可以用规范的方式下载jar包。因为jar包按规范的方式存在中央仓库中
-
jar包依赖的jar包需要手动添加
ex. fileupload组件->IO组件
(commons-fileupload-1.3.jar ->commons-io-2.0.1.jar)
如果所有jar包之间依赖需要自己了解清楚,那么就会极大增加学习成本Maven会自动将被依赖的jar包导入
03 Maven是什么 & maven的运行过程
- 服务于java平台的自动化构建工具
构建工具的发展:Make→Ant→Maven→Gradle - 构建:以Java源文件、框架配置文件、jsp、图片、HTML等作为“原材料”,去“生产”出一个可以运行的项目的过程
开发过程中,所有路径或配置文件中配置的类路径都是以编译结果为目录结构标准的
编译:java源文件[user.java]->Class字节码文件[user.class]->交给JVM去执行
部署:一个BS项目最后运行的并不是动态Web工程的本身,而是动态Web工程“编译的结果”
将项目按正确的目录结构部署到服务器上
搭建 - 构建过程中的几个主要环节:
【1】清理:删除以前的编译结果(class字节码文件),为重新编译做好准备
【2】编译:将Java源程序编译为class字节码文件
【3】测试:自动测试。自动调用junit文件。针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性
【4】报告:测试执行的结果
【5】打包: Java工程对应jar包,Web工程对象war包
【6】安装:在Maven特定的概念——Jar包或War包复制到本地仓库指定位置
【7】部署:将war包复制到Servlet容器的指定目录下,使其可以运行 - 安装maven核心程序
【1】检查java_home环境变量
/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
【2】官网下载maven,解压maven压缩包,放在非中文无空格路径下
/Users/jinshurui/Documents/apache-maven-3.6.3
【3】配置maven相关的环境变量
(1)vim ~/.bash_profile
(2)maven_home & m2_home
export M2_HOME=/User/maven/apache-maven-3.5.3
(3) path
export PATH=$PATH:$M2_HOME/bin
(4)source ~/.bash_profile
【4】验证:运行mvn -v查看版本
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /Users/jinshurui/Documents/apache-maven-3.6.3 Javaversion:1.8.0_162,vendor:OracleCorporation,runtime:/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.15.3", arch: "x86_64", family: "mac"
05 maven的核心概念
- 约定的目录结构
- POM
- 坐标
- 依赖
- 仓库
- 生命周期/插件/目标
- 继承
- 聚合
06 maven标准目录结构
- 创建约定的工程结构
【1】根目录:工程名
【2】src目录:源码
【3】pom.xml:maven核心配置文件
【4】main目录:存放主程序
【5】test目录:存放测试程序
【6】java目录:存放java源文件
【7】resources目录:存放框架或其他工具的配置文件 - 为什么要遵守?
- maven要负责项目的自动化构建。以编译为例,maven要想自动编译,那么它必须知道java源文件保存在哪
- 如果自定义的东西想让框架知道,有两种办法:
(1)以配置的方式告诉框架
(2)遵守框架内部已存在的约定 - 约定 > 配置 > 编码
07 Maven常用命令
- 执行与构建过程相关的Maven命令(编译,构建,部署),必须进入pom.xml 所在的目录
- 常用命令
【1】mvn clean : 清理(删掉target目录)
【2】mvn compile : 编译主程序(taget目录)
【3】mvn test-compile : 编译测试程序
【4】mvn test : 执行测试
【5】mvn package : 打包
【6】mvn install : 安装
【7】mvn site :生成站点
08 关于联网问题
- Maven 的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须有特定的插件来完成。而插件本身不包含在Maven核心程序中
- 当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找
- 本地仓库的默认位置:[系统登陆用户的家目录] \ .m2\repository
/Users/jinshurui/.m2/repository
- Maven核心程序如果在本地仓库中找不到需要的插件,那么它会自动连接外网,到中央仓库下载
- 如果此时无法连接外网,则构建失败
- 修改默认本地仓库的位置可以让Maven核心程序到我们事先准备好的目录下查找插件
【1】找到Maven解压目录\conf\settings.xml
【2】在setting.xml 文件中找到 localRepository 标签
【3】将 < localRepository>/path/to/local/repo< /localRepository>从注释中取出
【4】将标签体内容修改为自定义的Maven仓库目录
09 Pom
- 含义:Project Object Model 项目对象模型
DOM :Document Object Model 文档对象模型 - pom.xml 对于 Maven工程是核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置
10 坐标
- 数学中的坐标:
【1】在平面中,使用X,Y坐标可以唯一的定位平面中任何一个点
【2】在空间中,使用X,Y,Z三个向量可以唯一的定位空间中的任何一个点 - Maven的坐标:
使用下面三个向量在仓库中唯一定位一个Maven工程:
【1】groupid:公司或组织域名倒序+项目名
< groupid>com.atguigu.maven< /groupid>
【2】artifactid:模块名
< artifactid>Hello< /artifactid>
【3】version:版本
< version>1.0.0< /version>
- Maven 工程的坐标与仓库中路径的对应关系,以spring为例
11 仓库
-
仓库的分类
【1】本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
config->settings.xml
/Users/jinshurui/.m2/repository
【2】远程仓库
(1)私服:搭建在局域网环境中,为局域网范围内的所有Maven工程服务
(2)中央仓库:假设在Internet上,为全世界所有Maven工程服务
(3)中央仓库镜像:为了分担中央仓库流量,提升用户访问速度 -
仓库中保存的内容:Maven工程
【1】Maven自身所需要的插件
【2】第三方框架或工具的jar包
【3】我们自己开发的Maven工程
12 依赖
- maven解析依赖信息时会到本地仓库中查找被依赖的jar包
对于我们自己开发的Maven工程,使用install命令安装后就可以进入仓库 - 依赖的范围
【1】compile
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:参与
是否参与部署:参与
典型例子:spring-core
【2】test
对主程序是否有效:无效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子:Junit
【3】provided
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子:Servlet-api.jar - 依赖的传递性
【1】可传递的依赖不必在每个模块工程中重复申明,在最下面的工程依赖一次即可
【2】非compile范围的依赖不能传递。所以各个工程模块中,有需要就得重复申明依赖 - 依赖的排除
- 如果当前工程中引入了一个依赖A,而A又依赖了B,那么Maven会自动将A依赖的B引入当前工程,但是个别情况下B有可能是一个不稳定版本,或对当前工程有不良影响。这时我们可以在引入A的时候将B排除
设置方式:
<dependency>
<groupId>com.atguigu.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
<exclusions>
< exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</ exclusion>
</exclusions>
</dependency>
- 依赖的原则,作用:解决模块工程之间的jar包冲突问题
【1】路径最短者优先
MakeFriends选择近的HelloFriend下的dependency(2<3)
【2】路径相同时先声明者优先
先声明指的是depency标签的先后顺序 - 统一管理所依赖 .jar 包的版本
对同一个框架的一组jar包最好使用相同的版本。为了方便升级架构,可以将jar包的版本信息统一提取出来
【1】用properties标签内使用自定义标签统一声明版本号
<properties>
<atguigu.spring.version>4.1.1.RELEASE</atguigu.spring.version>
</properties>
【2】在需要统一版本的位置,使用${自定义标签名}引用声明的版本号
<dependency>
<version>${atguigu.spring.version}</version>
</dependency>
【3】properties标签配合自定义标签声明数据的配置不只能用于声明依赖的版本号。凡是需要统一申明后再引用的场合都可以使用
13 生命周期
- 各个构建环节执行的顺序:不能打乱顺序,必须按照既定的正确顺序来执行
- Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的
- Maven核心程序为了更好的实现自动化构建,按照这一特点执行生命周期中各个阶段:不论现在要执行生命周期中的哪一阶段,都是从这个生命周期最初的位置开始执行
- 插件和目标:
【1】生命周期的各个阶段仅仅定义了要执行的任务
【2】各个阶段和插件的目标是对应的
【3】相似的目标由特定的插件来完成
【4】可以将目标看做“调用插件功能的命令”
14 Eclipse中的使用
- Maven插件Eclipse已经内置
- Maven插件的设置: Window->Preferences->Maven
【1】installations : 指定Maven核心程序的位置。默认是插件自带的Maven程序,改为我们自己解压的那个。
【2】user settings : 指定Maven核心程序中 conf/settings.xml 文件的位置,进而获取本地仓库的位 - 基本操作
【1】创建Maven版的Java工程
【2】创建Maven版的Web工程
【3】执行Maven命令
15 继承
- 为什么需要,现状:
Hello依赖junit:4.0
HelloFirends依赖junit:4.0
MakeFriends依赖junit:4.9
由于test范围依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致 - 需求:统一管理各个模块工程中对junit依赖的版本
- 解决思路:将Junit依赖统一提取到“父”工程中,在子工程中声明Junit依赖是不指定版本,以父工程中统一设定的为准。同时也便于修改
- 操作步骤:
【1】创建一个Maven工程作为父工程。注意:打包方式为pom
【2】在子工程中声明对父工程的引用
relative path: 以当前文件为基准的父工程pom.xml文件的相对路径
【3】将子工程的坐标中与父工程坐标中重复的内容删除
【4】在父工程中统一管理Junit的依赖
dependency management
【5】在子工程中删除Junit依赖的版本号部分
注意:配置集成后,执行安装命令时要先安装父工程
16 聚合
- 作用:一键安装各个模块工程
- 配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块
- 使用方式:在聚合工程的pom.xml 上点右键->run as->maven install
17 Maven_Web工程的自动部署
在pom.xml添加以下信息,在terminal中执行mvn deploy 命令:
<!--配置当前工程构建过程中的特殊设置 -->
<build>
<finalName>AtguiguWeb</finalName>
<!-- 配置构建过程中需要使用的插件 -->
<plugins>
<plugin>
<!-- cargo是一家专门从事启动Servlet容器的组织 -->
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.3</version>
<!-- 针对插件进行的配置 -->
<configuration>
<!-- 配置当前系统中容器的位置 -->
<container>
<containerId>tomcat6x</containerId>
<home>D:\DevInstall\apache-tomcat-6.0.39</home>
</container>
<configuration>
<type>existing</type>
<home>D:\DevInstall\apache-tomcat-6.0.39</home>
<!-- 如果Tomcat端口为默认值8080则不必设置该属性 -->
<properties>
<cargo.servlet.port>8989</cargo.servlet.port>
</properties>
</configuration>
</configuration>
<!-- 配置插件在什么情况下执行 -->
<executions>
<execution>
<id>cargo-run</id>
<!-- 生命周期的阶段 -->
<phase>install</phase>
<goals>
<!-- 插件的目标 -->
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
18 找依赖信息的网站
我们可以到 http://mvnrepository.com/搜索需要的 jar 包的依赖信息
转载自:https://blog.csdn.net/zxm1306192988/article/details/76209062