Maven
1,什么是Maven
Maven是一个项目管理工具,它包含了一个项目对象模型(POM),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
Maven的核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定如何去编写java代码(一些目录结构),必须要按照这个规范来。
2,Maven可以解决的问题
- 当我们需要引入jar包时,每用到一个jar包都需要手动加入,如果是做一个比较大的工程,那么引入的jar包可能会非常多,这个时候就会很麻烦,而且可能会出现jar包冲突等问题。这个时候用Maven,它可以通过声明式依赖引入需要的资源
- 当写完一个java文件之后,需要把它编译为字节码文件,这个时候Maven就提供了一键编译项目的功能(虽然eclipse和idea也有这个功能)。
- 当写完一个项目测试的时候,如果一个一个功能手动去跑测试很麻烦。Maven可以一键自动化测试,然后生成测试报告。就很棒。
- 写好了代码之后,我们还需要把代码和各种配置文件一起,打包,如果是web项目,那么还需要发布到服务器,提供给别人使用。这个时候,Maven还可以自动化发布web项目。
3,依赖管理
传统的web项目中,我们引入的jar包是存放在lib目录。但是用Maven开发的项目,我们需要引入的jar包是存放在Maven的jar包仓库当中的。也就是说,我们用Maven开发项目时,不需要自己引入jar包,只要编写需要用的jar包所对应的坐标就好,使用的时候,Maven就会根据这个坐标找到仓库里面的jar包。
4,构建
一个项目,一般都需要经历编译,测试,运行,打包,安装,部署等一系列的过程。那么构建是什么?就是这一系列的过程都交给Maven进行管理,这个过程称为构建。而一键构建,就是指整个构建过程,使用Maven一个命令就可以轻松完成。Maven构建的流程:
清理 -> 编译 -> 测试 -> 生成测试报告 -> 打包 -> 部署
以上全部可以通过一个Maven命令完成
5,安装Maven
-
Maven官网下载地址:https://maven.apache.org/download.cgi
-
解压之后的目录:
- bin:Maven运行的命令,这里面有一个以后会经常使用的命令,mvn
- boot:存放了Maven自身运行需要用到的类加载器
- conf:Maven配置文件存放的目录
- lib:Maven依赖的jar包
- 设置MAVEN_HOME环境变量为Maven的安装目录:
- 将Maven的bin目录设置到Path环境变量下:
- 验证一下是否安装成功,在cmd里输入一个mvn -v命令:
这个样子就是安装成功了。
6,idea集成Maven插件
- 在File -> settings,找到maven:
- 设置maven的安装目录和settings文件:
- 在Runner上配置:
-DarchetypeCatalog=internal
这个配置的作用:
每次创建新项目的时候,idea都需要用插件来进行创建,这些插件每次都会去*仓库下载,这样创建就比较慢。这个配置就是让每次创建项目的时候,使用本地仓库中的插件进行创建项目。
7,使用骨架在idea中创建一个java的Maven工程
- 创建一个Module,选择Maven:
- 选中Create from archetype,选中下面这个骨架(就是项目的模板):
- 点开下面的区域,配置maven的工程坐标:
- GroupId:这个是jar包的组织结构,一般是域名倒序
- ArtifactId:这个表示模块的名字
- Version(版本):这个默认就好
8,Maven标准目录结构
Maven中的标准目录规范有以下几点:
- src/main/java:编写的代码部分
- src/main/resource:配置文件部分
- src/test/java:测试代码部分
- src/test/resource:测试配置文件部分
- src/main/webapp:创建web项目时,页面资源、css、js、html、jsp等的存放位置
9,仓库
Maven工程在工程内不会存放第三方jar包,这些第三方jar包都是通过坐标的方式去对应的jar包仓库里获取的。这个仓库的默认存储位置是:"C:\Users\Administrator.m2\repository"
修改这个默认目录:
- 创建一个目录:E:\softdata\maven_resp 用来存放
- 打开maven的配置文件,在settings标签里添加:
<localRepository>E:\softdata\maven_resp</localRepository>
10,Maven命令的基本使用
先打开cmd,进入模块的目录,比如:
- mvn clean:运行之后,模块中的target目录会被删除。target目录是maven编译打包之后存放class文件和jar文件的目录。
- mvn compile:运行之后,target目录又出现了,然后在target的classes目录下存放着java源代码编译之后的class文件。
- mvn test:这个命令,它会编译test里面的java文件,然后运行对应的单元测试代码,并且生成对应的单元测试报告。
- mvn package:对项目进行打包,这个命令首先会对项目中的java文件进行编译,编译好了之后进行单元测试,再进行打包,然后把打包好的jar文件存放在target目录下面。
- mvn install:这个命令还是会先对项目进行编译,测试,打包。然后把打好包的这个项目安装到本地的jar包仓库,这个方便以后其他的项目,如果要使用的话可以直接引用。
上面这些命令,每一个命令都是有一个插件来支撑的,这个插件在首次使用的时候,maven会自动去*仓库下载。
11,Maven的生命周期
对maven项目的构建分为几个阶段,分别是:
- 清除编译信息:mvn clean
- 编译:mvn compile
- 测试:mvn test
- 打包:mvn package
- 安装:mvn install
- 发布:mvn deploy
对于上面的构建阶段,一般可以分为两个生命周期:
- 清除编译信息(mvn clean),就是清理生命周期。
- 后面的五个命令表示默认的生命周期。这个生命周期一大显著特点是,当执行后面的一些命令时,前面的命令会自动执行一次。比如执行install命令,那么前面的compile、test、package会自动执行一次。
12,Maven创建javaweb工程
-
同样还是创建Maven工程
-
选择骨架:
记住选择的是maven-archetype-webapp
-
接着,填写坐标等信息,然后下一步
-
当idea上出现build success的时候,这个工程就已经创建好了。
-
这个时候会发现,创建的目录下只有src/main/webapp目录。那么如果想要写Java代码,就需要手动的补齐src/main/java目录
-
补齐了之后,在java目录下可能无法创建包和类,这个时候只要reimport一下就好了。
最后:可以发现的是,自己创建的目录结构其实和Maven标准的目录结构已经很接近了。并且没有引入一些不必要的东西,所以一般不用骨架创建项目也行。
13,Maven构建javaweb小案例
创建一个servlet,获取从页面上提交的name数据,然后在jsp页面上显示。
-
在src下创建一个包,然后在包里创建一个servlet。但是这个时候会看到创建的servlet在报错。这个是因为创建的maven的web工程里面一个jar包也没有,包括servlet api 和jsp api 的jar包都没有。
-
引入servlet api 和jsp api 的jar包,可以在pom.xml中配置servlet api的坐标,这个坐标可以去一个外网上找到:https://mvnrepository.com/
<dependencies>
<!-- 引入servlet-api -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 引入jsp-api -->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
引入之后,reimport一下就不会报错了。
-
编写对应代码
-
配置Tomcat服务器,然后启动项目。
-
启动项目后,访问页面,发现EL表达式无法正常使用。这个时候加入以下代码:
<%@ page isELIgnored="false" %>
属性isELIgnored:是否忽略el表达式,默认是true忽略el表达式。将这个属性值设置为false,就可以使用el表达式了。
14,maven插件方式部署web项目
之前的项目,每次运行都要启动一下Tomcat,非常耗时间。使用Maven之后,可以用Maven的Tomcat插件来快速启动项目。
但是Tomcat的Maven插件现在只支持到7的版本,而7的版本不支持servlet api 4.X版本,所以如果要使用插件方式来启动Tomcat,只能使用3.X版本的servlet api。
- 把servlet api换成3.X版本的:
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- 在build标签中引入Tomcat7,这个plugins标签一定要在pluginManagement标签外重新写一个:
<plugins>
<plugin>
<!-- 引入Tomcat7 -->
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>90</port>
<path>/mavenWeb</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
- 运行项目,直接找到tomcat7:run 双击就好:
现在,就不需要再配置Tomcat了。如果想要一次使用多个命令:
15,scope的作用
之前引入jsp api 和servlet api时,设置了一个属性:scope
<scope>provided</scope>
这个属性的作用是设置依赖的jar包的有效范围,具体取值如下:
- compile:默认的有效范围,在编译,运行,测试的时候都有效。
- provided:在编译和测试的时候有效,在运行时无效。比如servlet api,在运行项目的时候,tomcat容器就已经提供对应的jar包了,那这个时候就不需要maven再引入一次。
- runtime:在运行,测试的时候有效,但是在编译时无效。比如有些在编译时只需要用到接口的东西(jdbc驱动,druid连接池),只有在运行测试的时候才会用到具体的驱动和连接池。
- test:只有测试的时候有效,比如junit
- system:在编译和测试的时候有效,在运行时无效。和provided的区别是,使用system范围的依赖时,必须通过systemPath元素显式的指定依赖文件的路径。由于此类依赖不是通过maven仓库解析,而是与本机绑定,所以可能会造成不可移植的问题,因此一般不使用,只要知道有这么个值就行。