https://www.bilibili.com/video/BV1TW411g7hP?from=search&seid=14158829978266635696
记录下学习笔记。
目录
坐标 groupid、artifactid、version 用于在仓库中定位一个文件夹
Eclipse中,Maven工程的pom.xml添加依赖后的效果
生命周期中最后的部署deploy,用cargo: cargo.codehaus.org
Maven中的jar包所在目录查询 mvnrepository.com
先是视频中的先修知识总结:
已经掌握的技术:
要说明的是:
在控制层,最基本的技术是Servlet。对于框架,如果用的struts2,控制器就是Action,如果用的是SpringMVC,控制器就是Handler。
在业务层,Spring IOC是负责管理对象;AOP是做设计用的,是对业务设计的支持。所以可以说Spring在业务层有它的工作,但业务层的逻辑,是每个项目都不一样的,需要自己去设计。
在持久层,设计到增删改查的Java控制代码及SQL语句,最基本的是JDBC,还有对JDBC的其他封装---Aapache的DBUtils、Spring的JDBCTemplate、还有重量级的框架Hibernate和轻量级的框架MyBatis,企业里从2015年开始最常用的就是MyBatis了,因为简单。
用以上的技术,已经可以做出完整的项目。那为什么还需要Maven呢?
目前技术的问题
- 一个项目就是一个工程。
如果一个项目过于庞大,就不会使用package来划分模块,而是直接使用不同工程。
比如下图,一个模块就需要dao包、handler包、service包,对于一个工程,有多个模块,每个模块中都会有这些包。比如一个项目,几百人的团队,干好几年,这在JavaEE里是很常见的。所以这么多人都在一个工程里开发,是不合适的。那么如果把不同的模块放在不同的工程里,那一个项目就会有很多的工程,不同的模块组人员,在不同的工程中进行开发。那么Maven就能把一个项目拆分为多个工程,让多个工程之间互相访问。
- 项目中需要的Jar包,必须手动复制到WEB-INF/lib目录下
如果同样的Jar包重复出现在上面的不同的工程中,就浪费空间,而且不利于统一版本的管理。借助于Maven,我们在仓库中仅仅保存一份共享的Jar包,并且只需要引用,不需要复制到工程的WEB-INF/lib目录里。
比如通过maven的项目配置文件pom.xml中的设置,
maven的配置文件settings.xml存在于两个地方:
安装的地方:${M2_HOME}/conf/settings.xml
用户的目录:${user.home}/.m2/settings.xml
前者又被叫做全局配置,对操作系统的所有使用者生效;后者被称为用户配置,只对当前操作系统的使用者生效。
setting.xml是软件级别的配置;而pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,是项目级别的配置。
- Jar包需要别人替我们准备好,或者去百度搜索下载。
Jar包下载的麻烦,还有有些技术的官网就是通过maven或SVN(一种版本控制工具)来提供下载的。比如Mybatis的官网就是只提供maven的pom.xml中的依赖关系。
- 一个jar依赖的其他jar包,需要我们手动判断依赖关系。
典型的例子,做文件上传时,需要的Jar包,commons-fileupload-1.3.jar 依赖于 commons-io-2.0.1.jar,所以我们要手动管理起来非常麻烦。
Spring也有很多依赖关系:
core包依赖于commons-loggin包;
context包依赖于aop包,而aop包又依赖于aopalliance、beans、core包,非常复杂。
Maven是什么
是一款自动化的构建工具
MakeàAntàMavenàGradle
构建:以.java代码、XML框架配置文件、JSP、HTML、图片等素材,去编译、部署、搭建一个可运行的项目。
对于一个WEB项目,结构如下:
Build文件夹下面是src的源代码文件编译之后的类文件。
JRE System Library和Apache Tomcat下面的Jar包,都属于“运行时类库”。
运行时类库: 在编译期不做检查,只是一个引用,并没有复制到工程的目录下面。
比如String 这个类,在使用时不用import,因为它默认在rt.jar中,被导入。rt就是runtime的缩写。
如果移除JRE环境,再次添加的是这个:
如果是外部JAR,那么会加入工程的目录。
Web项目的目录结构,和编译结果的目录结构
Eclipse自动构建和部署的过程
Web工程中,在project中有自动build选项,默认开启。部署也是自动完成的,只要右键jsp在Tomcat中运行。
MAVEN的安装和配置
- 先检查JAVA_HOME环境变量,尽量有这个变量
Cmd中 echo %JAVA_HOME%
- 解压MAVEN核心程序的压缩表,不要有中文和空格路径
- 配置MAVEN自己相关的环境变量
MAVEN_HOME或M2_HOME
系统的path变量中增加MAVEN的bin目录
- 验证MAVEN:
mvn -v 如果能看到版本信息就行了。
MAVEN的核心概念
- 约定的目录结构
- POM
- 坐标
- 依赖
- 仓库
- 生命周期/插件/目标
- 继承
- 聚合
约定的目录结构
Hello
|---src
|---|---main
|---|---|---java
|---|---|---resources
|---|---test
|---|---|---java
|---|---|---resources
|---pom.xml
有些是在工程的web.xml中配置的,比如使用了Spring框架;
有些是使用目标工具,默认配置的,比如log4j在控制台打印日志,就必须使用上述资源文件名。
约定>配置>编码
约定是架构层面的事情,是经验;
能用配置解决的问题,就不写代码。
所以目录结构就是一种约定。
POM文件
POM的缩写: project object model ,与“构建”相关的一切内容都在pom.xml中配置。
类似DOM:document object model
pom.xml文件内容
<?xml version="1.0" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Hello</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
与构建过程相关的命令
比如编译、测试、打包、部署,比如进入pom.xml所在的目录(工程根目录)
[1]mvn clean 清理(之前编译过,再次编译之前最好清理)
[2]mvn compile 编译主程序
[3]mvn test-compile 编译测试程序
[4]mvn test 执行测试
[5]mvn package 打war包
生命周期、插件、目标
找到里面的标签:localRepository
把标签从注释里拿出来,改成自己的路径
mvn compile的效果
在web工程的hello目录之下,cmd中运行mvn compile ,会生成target文件夹,里面是classes文件夹。
因为之前在main文件夹的java文件夹下面,有一个Hello.java文件,所以编译得到的是Hello.class
mvn test-compile的效果
在target/test-classes下生成对应的test的目录。
mvn package的效果
surefre-reports是测试报告
最后的压缩文件就是打包生成的jar包,这里因为是java工程,不是web工程。
主程序会打包进去,测试程序不会在里面。
mvn clean的效果
会直接删除target文件夹。因为构建得到的产品,就是放在target目录下面。
坐标 groupid、artifactid、version 用于在仓库中定位一个文件夹
Maven里的模块,对应于eclipse中的工程的概念。可以多个工程(模块)组成一个项目。
每一个使用Maven的模块都有它的坐标,下面是一张本地仓库的截图, Spring的core模块的MAVEN坐标:
pom.xml文件在打包之后就会变成 .pom这样的文件。里面有坐标。
注意,按照.pom中的坐标,可以按目录结构找到结果。
上面的.pom文件所在的目录是:
org\springframework\spring-core\4.0.0.release\spring-core-4.0.0.release.pom
其中的文件名是: artifactId-version.pom
仓库respository
依赖
把当前工程加入到maven仓库中
引出:
另起一个工程HelloFriend,项目坐标:pom.xml中的内容
Snapshop快照,在版本中表示是不稳定版。而release代表稳定版。
HelloFriend类的代码中import了Hello类,那么编译时,如果报错 找不到依赖,就需要去查看和配置pom.xml中的依赖:
并且,要确定在仓库的文件夹中(自定义的类一般在本地仓库)确实有这样的类文件。
这里应该是: 本地仓库路径\com\atguigu\maven\Hello\0.0.1-snapshot\Hello-0.0.1-snapshot
这个文件是应该在Hello的目录中,执行cmd命令: mvn install ,就可以把当前工程加入到maven的仓库中。
仓库中一般都是pom文件和jar文件
这样再次编译HelloFriend工程,就不会报错了。
依赖的scope
依赖的子标签scope,其中compile和test、provided不同的取值,对test生效、对主程序生效、是否参与打包有不同的权限。
生命周期 执行后期的命令,前期命令也会顺便执行,自动化构建
Default生命周期Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:尤其注意 编译、测试编译、打包
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包
compile 编译项目的源代码
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录
test-compile 编译测试源代码
process-test-classestest 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如JAR。
pre-integration-test
integration-test
post-integration-test
verifyinstall将包安装至本地仓库,以让其它项目依赖。
deploy将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
Maven插件 及设置
指的是Maven提供给Web开发工具的插件。
设置eclipse里的Maven,在windowsàpreferences里,主要两个地方需要设置:
主要是 Installations和user settings需要设置。首先,点击installations里的add增加本地的maven解压后的主目录。
User settings 改为自己的maven解压之后的conf/setting.xml位置,这样就可以找到本地仓库的位置。
创建maven版的java工程
如果找不到,去windowsàcustomize perspective(用户观点)àMenu visibility
如果上面这里不勾选,就需要进而选择下面的maven-archetype-quickstart(java工程)
如果是web工程,选webapp;这里的选择,就是控制maven生成不同的约定结构。
但上图这么弄,出来的目录结构不全,会没有resources目录。
建完之后,默认是jdk1.5的,如果需要改版本,在工程的java build path和java compiler中都需要改。
还可以通过配置文件设置默认的jdk版本。
①设置通过Maven创建的工程的JDK版本——一劳永逸
[1]打开settings.xml文件
[2]找到profiles标签
[3]加入如下配置
<profile>
<id>jdk-1.7</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.7</jdk>
</activation>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
</properties>
</profile>
Eclipse里执行maven命令
右键一个maven工程的Pom.xml,选择Run as。。。就可以鼠标点选执行。
如果要执行mvn compile,选择 build….,然后在goals里输入compile
创建maven版的web工程
一开始和java工程一样,勾选简单创建。Eclipse在接下来的打包方式上,选择war方式。
这样eclipse就知道是建web工程,maven会帮助建立工程结构。
其实对eclipse来说,它只是一个maven工程,但对maven来说它就知道是web工程。
Maven会在main文件夹下,建立一个webapp文件夹。
对比右边的eclipse版的web工程,标准web工程应该有WEB-INF和里面的web.xml
所以要设置下:
右键工程àpropertiesàproject facetsàDynamic Web module取消勾选并应用à再次勾选,之后选择下面的Futher configuration availableà把里面的webcontent改为maven的 src/main/webapp,则以后,maven的webapp就相当于是eclipse的web工程的webcontent。
确定之后会自动生成web.xml,如下面右图。
这样,就很方便在xml文件上 run as sever,之类的,方便运行。
接下来就是麻烦一点的,如果你建一个jsp文件,会提示缺少一些类库
此时,当然可以右键工程àadd libraryàServer Runtimeà选择Apache tomcat添加。
但这是eclipse的方式,我们应该使用maven的方式添加依赖。
我们用ctrl+shifp+p 来查找该类属于哪一个API,
点击双向箭头,就定位到属于 servlet-api.jar这个jar包。
接着在pom.xml中添加依赖。
- ServletAPI依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
- JSPAPI依赖
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1.3-b06</version>
<scope>provided</scope>
</dependency>
注意,这两个依赖尽量都设置为provided,免得发生和Tomcat的jar包冲突,产生不可预料的错误。
比如JSP的空指针异常错误。
(或者你直接从Tomcat的lib里拿这两个jar包到maven的本地仓库里,就可以用compile默认的范围)
导入maven工程
如果你的maven工程是手动创建的,而不是用eclipse去创建的,你得用下面的方式去导入。
如果本身就是eclipse方式创建的maven工程,可以用genernal下的Existing projects into workspace即可。
Eclipse中,Maven工程的pom.xml添加依赖后的效果
比如Hello工程的pom.xml中,添加了spring-core的依赖,之后就会显示在 Maven的运行库上。
依赖的传递性
因为spring-core本身会依赖于commons-logging,那么当你配置spring-core的依赖时,commons-logging也会自动被导入。
如果一个maven工程中,配置了依赖于另一个
并且需要仓库中有相关的工程jar包。可以到HelloFriend工程中进行mvn install
注意,必须范围scope是compile范围的才能传递。test范围的依赖不能传递。
传递性的 默认就近优先传递原则
如果非要依赖2.17,就在makeFriends中显式地声明出。
依赖的深度相同时,先声明的依赖优先。
统一管理依赖 通过自定义pom.xml中的常量
如果需要把所有的spring框架各个jar包都升级到新的统一版本,怎么做比较方便?
如果你去pom.xml里,一个个依赖去改<version>标签,那就太麻烦了。
我们可以自定义一个pom.xml里的常量,通过标签<properties>,之后在要引用的<version>位置处进行引用。
上面是定义,下面是引用:在每个依赖的后面用常量去定义,这样只要改一个最初的定义即可全部更改。
maven工程的继承
需求:如果树形结构的各个工程中,想拥有相同的jar包版本,就可以用maven的继承。
在父工程里,打包方式得是pom,而不是jar和war
上面是在新建父工程时pom.xml中的配置要点,这些你在eclipse里新建之后是自动加进去的。
在子工程中声明对父工程的引用
尽量配置上一个relativePath标签。
删除子工程的坐标中,与父工程重复的标签<groupId>和<version>
配置完成后,子工程的坐标中,会提示:groupId is duplicate of parent groupId
如上图,当你配置了本工程的父工程的groupId和version之后,本工程的这两个坐标就不用配置了。
因为坐标就是控制目录的,所以父子工程在maven仓库中,应该在同一个目录下面。文件名(工程名)不同。
在父工程中统一管理依赖
在父工程的pom.xml配置依赖管理标签 <dependecyManagement>
对应的子工程的依赖中,就不再需要<version>。
继承之后的install
如果做了工程之间的继承,那么要先install父工程,否则就会报错。
聚合之后,一键install
因为继承之后,需要先install父工程,才能install子工程。这就有了聚合的概念。
在一个总的聚合工程中(可以是父工程来做,也可以另外建一个工程去做聚合),配置各个参与模块的相对路径。
利用pom.mxl的标签<modules>
比如在父工程中,配置三个子工程的相对路径。
经过聚合之后,在聚合工程的pom.xml上,运行 run as à maven install就可以了。
生命周期中最后的部署deploy,用cargo: cargo.codehaus.org
最常规的方式,通过eclipse去编译、部署、运行,就是在index.jsp上直接run asà Run on Server
如果要通过maven,则常规方式是手动 pom.xml à run as à maven build … àgoals中输入package,打包。
打包之后,---
打包之后,会在target目录下生成一个war包。把war包放在Tomcat的webapps目录下,就可以运行。
war 是什么?里面有什么东西?
a. web.app所有必需的文件都在target/app目录下,我们称之为webroot,打包也就是将webroot打包成.war后缀的压缩包
b. 所有页面文本都在webroot目录下
c. 所有的后台代码都编译成.class文件,放在webroot/WEB-INF/classes目录下
d. 所有依赖的jar包都放到webroot/WEB-INF/lib目录下
e. 命令打包后,app.war包将会出现在target目录下,也就是与webroot同级别
手动部署的步骤为:
1.将app.war包copy到tomcat安装的webapps目录下
2.在tomcat安装的bin目录下点击startup.bat启动,此时会将webapps/app.war包文件解压成文件夹(如果tomcat已启动,此时copy的war包会自动解压,不用重启。
3.浏览器输入:localhost:8080/app/index.jsp正式访问!
Maven的自动化部署,利用cargo来做
配置完上面之后,就可以pom.xml à run as à maven build … àgoals中输入deploy
进行自动部署,并运行Tomcat。
但在eclipse里,启动之后停止不了。即使红色暂停之后,还是不行,端口号是被占用的。
这个deploy命令,最好是在cmd里进行使用,这样ctrl+c就可以停止,并关闭端口。
用完你就会发现,还是用 index.jsp àRun on Server更简单。。。。。。。
所以只是了解这个过程。还是eclipse好用。
Maven中的jar包所在目录查询 mvnrepository.com
https://mvnrepository.com
搜索需要的jar包的依赖信息。
比如搜索spring core,然后找到对应版本,点进去就能看到依赖信息