Maven入门
一、Maven的概念
Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
二、Maven的功能
帮助开发者完成以下工作:构建、文档生成、报告、依赖、SCMs、发布、分发、邮件列表
三、什么是项目构建
项目构建是一个项目从编写源代码到编译、测试、打包、部署、运行的过程。
Ⅰ、传统项目构建
构建过程如下:
1、创建一个Java web 工程
2、在工程中编写源代码及配置文件等
3、对源代码进行编译(Java文件编译成class文件)
4、执行Junit单元测试
5、将工程打成war包部署到tomcat运行
Ⅱ、maven项目构建
上图中部分阶段对应命令如下:
编译:mvn compile --src/main/java目录java源码编译生成class (target目录下)
测试:mvn test --src/test/java 目录编译
清理:mvn clean --删除target目录,也就是将class文件等删除
打包:mvn package --生成压缩文件:java项目#jar包;web项目#war包,也是放在target目录下
安装:mvn install --将压缩文件(jar或者war)上传到本地仓库
部署|发布:mvn deploy --将压缩文件上传私服
其他命令:
mvn eclipse:eclipse -- maven java或web项目转换Eclipse工程
mvn eclipse:clean -- 清除eclipse设置信息,从eclipse工程转换为maven原生项目了
mvn idea:idea -- maven java或web项目转换IDEA工程
mvn idea:clean -- 清除IDEA设置信息,从IDEA工程转换为maven原生项目了
mvn tomcat:run -- 将maven项目部署到tomcat上,并运行
maven项目的完整生命周期
当执行生命周期命令时,此命令前面的指令都会自动执行,比如我们执行mvn install对项目进行上传至本地仓库时,那么前面所有的步骤(如:源代码的编译,打包等等)将会自动执行。
maven项目构建的有点:
一个命令(mvn tomcat:run)完成项目构建、运行,方便快捷
四、什么是依赖管理
依赖:一个Java项目可能要使用一些第三方的jar包才能运行,那么这个Java项目依赖了这些第三方jar包
例如:一个crm系统,它的架构是SSH框架,该crm项目依赖SSH框架,具体依赖的Hibernate、Spring、Struts2.
依赖管理:对项目所有依赖的jar包进行规范化管理
Ⅰ、传统项目依赖管理
传统的项目要管理所依赖的jar包完全靠人工进行,从网上下载jar包添加到项目中,如图:需要手动将Hibernate、struts2、spring的jar包添加到项目的WEB-INF/lib的目录下
手动添加的问题:
1、jar包的版本容易冲突
2、jar包查找不方便
3、jar包过多导致项目过大
Ⅱ、Maven项目依赖管理
maven项目管理所依赖的jar包不需要手动向项目中添加jar包,只需要在pom.xml(maven项目的配置文件)添加jar包的坐标,就会自动从maven仓库中下载jar包
maven项目依赖管理优点:
1、通过pom.xml文件对jar包的版本进行统一管理,避免版本冲突
2、maven维护一个非常全面的maven仓库,maven项目可以自动从maven仓库下载所需jar包,非常方便
五、Maven安装
Ⅰ、下载https://maven.apache.org/download.cgi
Ⅱ、解压下载Maven的压缩包
bin目录:存放一些可操作cmd命令
boot目录:存放maven运行需要的类加载器
conf目录:存放配置文件,settings.xml整个maven工具核心配置文件
lib目录:maven运行依赖jar包
Ⅲ、环境变量配置
前提:电脑上需配置Java环境,JDK1.7+版本
将%MAVEN_HOME%\bin加入环境变量path
管理员身份启动CMD,并通过mvn -v命令检查maven是否配置成功
看到maven版本和Java版本几位配置成功
六、Maven仓库
Ⅰ、本地仓库
本地仓库:用来存储从私服仓库或中央仓库下载的插件和jar包,项目优先从本地仓库查找
默认本地仓库位置在${user.dir}/.m2/repository,${user.dir}表示widows用户目录
配置本地仓库:在MAVEN_HOME/conf/settings.xml文件中配置本地仓库位置(本地仓库下载:链接: https://pan.baidu.com/s/1a5JSZNAzDKLilGHU5Ek-uA 提取码: b562 复制这段内容后打开百度网盘手机App,操作更方便哦)
<!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> --> <localRepository>D:\workspace\repo</localRepository>
Ⅱ、私服仓库
私服仓库:远程服务器或局域网服务器中的仓库
Ⅲ、中央仓库
中央仓库:在maven软件中内置一个远程仓库地址http://repo1.maven.org/maven2,服务于整个互联网,它是由Maven团队维护。
七、Eclipse和Maven
一些高版本eclipse已经内置了maven,如果想使用自己下载的maven
下载并解压的maven路径
再设置settings.xml路径
注意:如果修改了settings.xml文件内容需要点击上图的“update settings”按钮,点击Reindex按钮对本地仓库重建索引
eclipse浏览仓库
Window=>show view=>other
八、构建Maven web项目
Ⅰ、需求
创建一个web工程,实现入门程序的功能
1、添加index.jsp,输出hello world
2、添加一个servlet转发到jsp页面
Ⅱ、创建maven工程
错误原因:违反Maven项目目录约定,webapp目录中没有WEB-INF和web.xml
解决方案:通过下图方法快速生成web工程标准结构
Ⅲ、设置编译版本
查看上图编译版本为1.5,我们使用jdk1.8,通过maven 插件来设置
添加configuration节点
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <!-- 源码版本 --> <source>1.8</source> <!-- 编译目标版本 --> <target>1.8</target> <!-- 指定编码 --> <encoding>utf-8</encoding> </configuration> </plugin> </plugins> </build>
Ⅳ、编写Servlet
页面有错误提示,原因是缺少Servlet的jar包
解决方案:引入servlet的jar包,
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency>
注意:
1、pom.xml的内容变化,需要Maven=>update project..
2、内容包括:groupId:项目名称,类似报名,唯一性、artifactId:模块名称、version:版本号、type:依赖的类型,比如是jar包还是war包等,默认为jar,表示依赖的jar包
3、<type>pom.lastUpdated</type> lastUpdated的意思:表示使用更新描述信息,占位符作用,jar包不会被加载进来,只是将该jar包的一些描述信息加载进来。
编写Servlet具体代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Hellow Servlet"); request.getRequestDispatcher("/index.jsp").forward(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); }
Ⅴ、编写jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> Hellow word </body> </html>
注意:jsp文件最后也要被编译成字节码文件(xxx_jsp.class),编译jsp的字节码文件就需要相应的jar包处理
Ⅵ、运行
两种运行方式:1、使用自己创建的Server服务器,2、使用Maven内置的tomcat,
使用第二种方式需要引入tomcat插件
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <!-- 端口号 --> <port>8080</port> <!-- 项目路径 --> <path>/hellowword</path> <!-- 编码 --> <uriEncoding>utf-8</uriEncoding> </configuration> </plugin>
右击Run As Maven build..
输入:tomcat7:run命令
点击Run按钮得到,复制 http://localhost:8080/hellowword
出错了:HTTP Status 500 - java.lang.LinkageError: loader constraint violation: loader
原因:javax.servlet.jar和javax.servlet.jsp.jar两个文件在项目运行时和tomcat中这个两个jar包冲突所导致的。
解决方案:修改jar包的作用范围,scope:provided
Scope各种取值详解
scope取值 | 有效范围(compile, runtime, test) | 依赖传递 | 例子 |
---|---|---|---|
compile | all | 是 | spring-core |
provided | compile, test | 否 | servlet-api |
runtime | runtime, test | 是 | JDBC驱动 |
test | test | 否 | JUnit |
system | compile, test | 是 |
compile :为默认的依赖有效范围。如果在定义依赖关系的时候,没有明确指定依赖有效范围的话,则默认采用该依赖有效范围。此种依赖,在编译、运行、测试时均有效。
provided :在编译、测试时有效,但是在运行时无效。例如:servlet-api,运行项目时,容器已经提供,就不需要Maven重复地引入一遍了。
runtime :在运行、测试时有效,但是在编译代码时无效。例如:JDBC驱动实现,项目代码编译只需要JDK提供的JDBC接口,只有在测试或运行项目时才需要实现上述接口的具体JDBC驱动。
test :只在测试时有效,例如:JUnit。
system :在编译、测试时有效,但是在运行时无效。和provided的区别是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量。
七、pom.xml的依赖关系讲解(重点)
Ⅰ、使用网站搜索[从中央仓库拿]
步骤一:百度搜索关键字“maven repository”
步骤二:输入关键字查询获得需要内容,确定需要版本
步骤三、获得坐标
Ⅱ、使用本地仓库,通过eclipse获得坐标 上面有具体做法 (工程项目=>右击=>maven=>Add Dependency)
Ⅲ、依赖相关配置
依赖传递的:A项目 依赖 B项目,B项目 依赖 C项目,当使用A项目时,就会把B也给加载进来,这是传递依赖,依次类推,C也会因此给加载进来。
optional:是否依赖。默认值false(不依赖)
比如struts2中内置了log4j这个记录日志的功能,就是将log4j内嵌入struts2的jar包中,而struts2有没有log4j这个东西都没关系,也能够运行,就可以对它进行可选操作,不想要,就设置为false。
exclusions:排除传递依赖,解决jar冲突问题
jar冲突
1、添加依赖
2、先添加struts2-spring-plugin 再添加spring-beans
3、使用exclusions来配置
struts2-spring-plugin依赖的spring-core的版本排除依赖了,也就是该依赖的spring-core不会在加载进来
查看代码,在struts2-spring-plugin中排除依赖spring-core,但是spring-beans中也排除了,所以删除要删除红框中的代码
Ⅳ、依赖调节原则
maven解决传递依赖时jar包冲突问题的方法,按照两种原则,上面已经介绍了一种了,就是下面的第二原则
1、第一原则:路径近者优先原则
A-->B-->C-->D-->X(1.6)
E-->D-->X(2.0)
使用X(2.0),因为其路径更近
2、第二原则:第一声明者优先原则。就是如果路径相同,maven 默认配置在前面的优先使用
A-->B --> X(1.6)
C-->D--> X(2.0)
这样就是路径相同,那么如果A在前面,C在后面,则使用X(1.6)