1.Maven
项目构建、依赖管理。
项目构建:项目开发过程中,遇到的各种阶段,maven都可以很轻松地帮助我们来解决。比如编译、测试、打包、等等操作。极大地简化开发工作量。
依赖管理:EE项目有哪些痛点?
1.频繁地去导包。仅仅针对编译阶段需要导入jar包来分析,新建一个项目就需要导入对应的jar包,否则无法编译通过。
Add as library有什么功能?就相当于指令:-classpath 相应的jar包。那我能不能将这些jar包统一放置在一个地方,比如仓库里面,需要什么jar包,就直接给这个jar包的地址到这个classpath,不需要再每个项目中频繁地去导包,然后add as libraay。
2.有些jar包的运行需要依赖包支撑。fileupload包运行需要有io包。如果两个包的版本不匹配,那么这个时候,仍然无法运行。maven会自动的帮助我们将jar包的依赖包加入进来。
https://mvnrepository.com/
1.1.maven的安装
jar包用我提供给大家的。
1.1.1.设置环境变量
同java。
1.1.2.设置国内镜像
在conf/settings.xml文件中Mirrors节点下新增如下:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
Note:如果之前没设置镜像之前下载了部分插件,但是没有下载成功(运行时出错),可以到本地仓库中将这些jar包删了,重新下载就行了。
1.1.3.本地仓库
可选的。可以设置也可以不设置。对于windows系统来说,默认放在c盘,如果你经常重装系统,可以将该路径更改一下。建议不要设置空格、中文目录下。
d:repository
1.2.项目构建
maven可以帮助我们非常轻松地完成编译、测试、运行、打包等操作。
1.2.1.编译
编译对应的maven指令时mvn compile
缺少一个配置文件。需要在当前应用project目录下新建一个pom.xml文件(文件名称必须一致)
运用这三个标签去界定唯一的一个项目出来。
公司id-----项目id-----版本号
接下来,执行下面指令:
mvn compile
没有报错,但是没有任何编译产物产生。
为什么呢??????
规则:预定大于配置。在软件开发过程中,有一些约定俗成的规则,虽然说没有在配置文件里面主动的去配置,但是大家一般都默认遵守这个规则。maven的文件存放就遵循着一个规则:
java文件:src/main/java目录下
配置文件:src/main/resources目录下
如果你写了一些测试代码,那么应当放在哪里呢?
测试java文件:src/test/java
测试需要的配置文件:src/test/resources目录下
此时就编译通过了。
1.2.2.测试
maven也可以帮助我们进行自动化测试。只需要写好对应的测试代码,maven就会帮助我们自动去运行。
你需要去做的就是在指定的目录下去编写测试代码。当执行mvn test指令时,会自动去到src/test/java目录下执行全部的单元测试用例。
为什么添加@Test注解就可以执行了?
其实里面就是利用了反射。
1.2.3.打包
想把项目的代码打包,jar包或者war包。
mvn package
默认情况下打成jar包,如果需要打成war包,需要写明。
1.2.4.还有一个高频指令
mvn clean
:用于清除编译产物
1.3.依赖管理
帮助我们去管理jar包。
项目中使用一个jar包,只需要去写出该jar包的坐标即可。
坐标:
比如在平面或者空间坐标系,用于标识唯一的一个点。同样,在众多的maven项目中jar包,如何去找到你的这个jar包。
groupId、artifactId、version标识唯一的一个jar包
你写出jar包的坐标,maven是怎么帮助你把jar包加载到内存中的呢?
到服务器上面去搜寻对应的jar包。—这个服务器就是中央仓库。
第一次去中央仓库下载的jar包直接缓存在本地,下次再次使用的时候,直接将本地的jar包加载到内存中-------本地仓库。
中央仓库位于国外,下载速度一般比较慢,可以设置一个国内的镜像。
之前se、ee项目编译:
新建一个目录,里面放入jar包,然后需要add as library(这一步其实相当于告诉IDEA,接下来需要通过-classpath xxxjar包将这个加载到内存中)
maven管理jar包,不需要这么操作了,只需要拟引入对应的坐标即可。那么maven会自动帮助你把这些jar包加载到内存中,然后编译通过。
1.3.1.如何查找坐标
https://mvnrepository.com/
https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.3.2
不需要去记。
1.3.2.jar包的scope
compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效(有效指的是可以找得到)
test:测试依赖范围。只对于测试classpath有效。(JUnit单元测试用这个就行)
provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
runtime:运行时提供。例如:jdbc驱动
默认compile级别。大多数jar包的一个scope。
但是需要注意几个特殊的
比如test的junit。设置compile也没有问题,但是没有必要,因为运行时不需要。
provided的servlet。不可以设置compile,设置了以后会和tomcat的冲突。
runtime的mysql-connector-java。设置compile也没问题,但是没有必要。
1.3.3.依赖传递
依赖是可以传递的。项目A依赖了jar包B,项目C依赖了项目A,那么一般情况下,项目C可以直接得到jar包B,而不需要再去引入依赖。
1.3.3.1.IDEA里开发Maven项目
接下来做如下设置:点击setting,然后在搜索栏搜索:maven
勾选自己的maven地址,同时如果你修改了仓库,那么需要使用这个xml文件,然后重新指定仓库。
还有一点。如果你的IDEA是2020版的,可能会出现一些问题。
如果在写dependencies中发现没有提示,去setting中
Update一下。
写完dependencies后,点击以下
我选的enable auto-import
如果想取消,改成import changes的话,去掉红框中的勾勾即可
Demo1----依赖fileupload,demo2依赖demo1
依赖是可以传递的。
但是需要特别注意一点,不是所有的jar包都可以传递过来。
Demo2依赖demo1,demo1依赖jar包,如果这个jar包是servlet或者junit,那么该依赖无法传递到demo2.
1.3.4.依赖冲突
比如项目引用了依赖A,A引用依赖C(v1.1)
引用了依赖B,B引用依赖C(v1.2)
但是使用了两个不同的版本
项目 依赖Spring-contex,Spring-contex依赖Spring-beans 5.2.2.RELEASE
依赖Spring-jdbc,Spring-jdbc依赖Spring-beans 5.2.1.RELEASE
1.3.5.第一声明者优先
谁先声明用谁的
1.3.6.路径近者优先
项目 依赖Spring-contex,Spring-contex依赖Spring-beans 5.2.2.RELEASE
依赖Spring-beans 5.2.1.RELEASE
1.3.7.依赖排除
将某个依赖里面,不需要的依赖排除出去,防止出现冲突
1.3.8.抽提变量
处理spring系列jar包时采用的策略
1.4.maven生命周期
包含彼此独立的三个阶段
Clean
Default
Site(很不常用)
每个阶段都有一个或者多个指令组成。
当你执行某个阶段的指令时,该阶段内该指令前所有的指令都会被执行。
生命周期没有做实现,仅仅是做了一个规范。
具体的实现由插件来完成。
mvn的指令可以组合一起使用。比如mvn clean compile/package
1.5.用IDEA开发一个Maven的EE项目
步骤和之前开发Maven SE项目大体相同。
新建项目过程和之前Maven SE完全相同。接下来需要做一些设置。
首先给当前这个应用添加一个web根目录
根目录的位置建议放在:
src\main\webapp,即把web改成src\main\webapp
设置完这个web以后,发现webapp目录有了一个小蓝点,小蓝点表示他不是一个普通的目录,而是一个web根目录,接下来webapp目录下的所有东西都会原封不动的复制到部署根目录。
接下来设置artifacts
有一个name,同时有一个output路径(部署根目录),部署根目录里面有什么呢?
上面这个目录不就是标准的EE项目目录结构吗?
最后一步,将output路径也就是部署根目录,拿到tomcat里面去做一个虚拟映射,就完成了部署。
点击add configuration
只需要添加一个tomcat,然后将部署根目录的artifacts放入到这个里面,就完成了部署。
新建servlet,发现全部报错
原因,为什么?
编译找不到jar包。
这样做即可:
留心看一下编译的jdk版本?
Maven默认的这个编译版本是1.5,会有很多性能不支持。需要去确认一下。
应当改成8(即jdk1.8)
先抛开编译的问题
接下来,导入fileupload包
报错:
此时会发现WEB-INF目录下压根没有lib,所以运行时找不到jar包。
此时真正的问题在于没法将lib复制到WEB-INF下面
1.5.1.解决方案一
把需要的jar包复制到WEB-INF/lib目录中。
可能你仅仅需要导入上述三个包,但是commons-fileupload依赖于commons-io,如果你不知道这一点,很可能就不把commons-io包导入了。
并且servlet-api这个包并不需要导入到部署目录中,因为它的scope应该是provide
做完上述步骤之后应当先clean再compile。
方式一,不推荐!!!
1.5.2.解决方案二
创建一个新Moudle:maven_ee2
然后在pom.xml文件中添加这句:
这句就表示你希望将次项目打成war包,这个war包就可以直接扔到服务器中进行部署。
就会自动帮我们生成两个artifacts
最后去部署它
1.6.Maven默认的这个编译版本1.5
Maven的settings.xml文件在profiles节点下新增
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
maven默认编译的产物版本是1.5.很多高级特性没法显示。
New HashMap();编译的时候就会出错。
得想办法将maven的编译版本设置为1.8.
得让IDEA使用我们自己下载的Maven。
接下来需要做一步
1.在maven的settings.xml文件中新增profile节点
2.将IDEA使用的maven变成自己本地安装的maven