第一章
1 主要内容
2. Maven的简介
2.1. 简介
Maven【[ˈmevən]】这个词可以翻译为"专家",“内行”。 作为Apache组织中的一个颇为成功的开源项
目,Maven主要服务于基于java平台的项目构建,依赖管理和项目信息管理。
无论是小型的开源类库项目,还是大型的企业级应用; 无论是传统的瀑布式开发,还是流行的敏捷开
发,Maven都能大显身手。
2.2. 项目构建
不管你是否意识到,构建(build)是每一位程序员每天都在做的工作。早上来到公司,我们做的第一
件事就是从源码库签出最新的代码,然后进行单元测试,如果测试失败,会找相关的同事一起调试,修
复错误代码。 接着回到自己的工作上来,编写自己的单元测试及产品代码。
仔细总结一下,我们会发现,除了编写源代码,我们每天有相当一部分时间花在了编译,运行单元测
试,生成文档,打包和部署等繁琐且不起眼的工作上,这就是构建。 如果我们现在还手工这样做,那成
本也太高了,于是有人用软件的方法让这一系列工作完全自动化,使得软件的构建可以像全自动流水线
一样,只需要一条简单的命令,所有繁琐的步骤都能够自动完成,很快就能得到最终结果。
2.3. 项目构建工具
Ant构建
最早的构建工具,基于IDE, 大概是2000年有的,当时是最流行java构建工具,不过它的XML脚本编写
格式让XML文件特别大。对工程构建过程中的过程控制特别好
Maven【JAVA】
项目对象模型,通过其描述信息来管理项目的构建,报告和文档的软件项目管理工具。它填补了Ant
缺点,Maven第一次支持了从网络上下载的功能,仍然采用xml作为配置文件格式。Maven专注的是依
赖管理,使用Java编写。
Gradle
属于结合以上两个的优点,它继承了Ant的灵活和Maven的生命周期管理,它最后被google作为了
Android御用管理工具。它最大的区别是不用XML作为配置文件格式,采用了DSL格式,使得脚本更加简
洁。
目前市面上Ant比较老,所以一般是一些比较传统的软件企业公司使用,Maven使用Java编写, 是当
下大多数互联网公司会使用的一个构建工具, 中文文档也比较齐全, gradle是用groovy编写,目前比较
新型的构建工具一些初创互联网公司会使用,以后会有很大的使用空间。
2.4. Maven的四大特性
2.4.1. 依赖管理系统
Maven为Java世界引入了一个新的依赖管理系统jar包管理 jar 升级时修改配置文件即可。在Java世界
中,可以用groupId、artifactId、version组成的Coordination(坐标)唯一标识一个依赖。
任何基于Maven构建的项目自身也必须定义这三项属性,生成的包可以是Jar包,也可以是war包或者
jar包。一个典型的依赖引用如下所示:
<dependency>
<groupId>javax.servlet</groupId> com.baidu
<artifactId>javax.servlet-api</artifactId> mysql-connector
<version>3.1.0</version>
</dependency>
坐标属性的理解
Maven坐标为各种组件引入了秩序,任何一个组件都必须明确定义自己的坐标。
groupId
定义当前Maven项目隶属的实际项目-公司名称。(jar包所在仓库路径) 由于Maven中模块的概念,
因此一个实际项目往往会被划分为很多模块。 比如spring是一个实际项目,其对应的Maven模块会有很
多,如spring-core,spring-webmvc等。
artifactId
该元素定义实际项目中的一个Maven模块-项目名, 推荐的做法是使用实际项目名称作为artifactId的
前缀。 比如: spring-bean、 spring-webmvc等。
version
该元素定义Maven项目当前所处的版本。
2.4.2. 多模块构建
项目复查时 dao service controller 层分离将一个项目分解为多个模块已经是很通用的一种方式。
在Maven中需要定义一个parent POM作为一组module的聚合POM。在该POM中可以使用 标签来定
义一组子模块。parent POM不会有什么实际构建产出。而parent POM中的build配置以及依赖配置都
会自动继承给子module。
2.4.3. 一致的项目结构
Ant时代大家创建Java项目目录时比较随意,然后通过Ant配置指定哪些属于source,那些属于
testSource等。而Maven在设计之初的理念就是Conversion over configuration(约定大于配置)。其
制定了一套项目目录结构作为标准的Java项目结构,解决不同ide 带来的文件目录不一致问题。
2.4.4. 一致的构建模型和插件机制
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<contextPath>/test</contextPath>
</configuration>
</plugin>
3. Maven的安装配置和目录结构
3.1. Maven的安装配置
3.1.1. 检查JDK的版本
JDK版本11及以上版本
3.1.2. 下载Maven
下载地址:http://maven.apache.org/download.html
3.1.3. 配置Maven环境变量
解压后把Maven的根目录配置到系统环境变量中MAVEN_HOME,将bin目录配置到path变量中。
注:maven解压后存放的目录不要包含中文和空格
3.1.4. 检查Maven是否安装成功
打开dos窗口,执行 mvn -v
3.2. 认识Maven目录结构
Maven项目目录结构
3.3 注意
1.1.修改默认仓库位置
打开maven目录 -> conf -> settings.xml
添加仓库位置配置 <localRepository>F:/m2/repository</localRepository>
注:仓库位置改为自己本机的指定目录,"/"不要写反
1.2.更换阿里镜像,加快依赖下载
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
4. Maven命令
作为开发利器的maven,为我们提供了十分丰富的命令,了解maven的命令行操作并熟练运用常见的
maven命令还是十分必要的,即使譬如IDEA等工具给我提供了图形界面化工具,但其底层还是依靠
maven命令来驱动的。
Maven的命令格式如下
mvn [plugin-name]:[goal-name]
命令代表的含义:执行 plugin-name 插件的 goal-name 目标
4.1. 常用命令
命令 | 描述 |
---|---|
mvn –version | 显示版本信息 |
mvn clean | 清理项目生产的临时文件,一般是模块下的target目录 |
mvn compile | 编译源代码,一般编译模块下的src/main/java目录 |
mvn package | 项目打包工具,会在模块下的target目录生成jar或war等文件 |
mvn test | 测试命令,或执行src/test/java/下junit的测试用例. |
mvn install | 将打包的jar/war文件复制到你的本地仓库中,供其他模块使用 |
mvn deploy | 将打包的文件发布到远程参考,提供其他人员进行下载依赖 |
mvn site | 生成项目相关信息的网站 |
mvn eclipse:eclipse | 将项目转化为Eclipse项目 |
mvn dependency:tree | 打印出项目的整个依赖树 |
mvn archetype:generate | 创建Maven的普通java项目 |
mvn tomcat7:run | 在tomcat容器中运行web应用 |
mvn jetty:run | 调用 Jetty 插件的 Run 目标在 Jetty Servlet 容器中启动 web 应用 |
注意:运行maven命令的时候,首先需要定位到maven项目的目录,也就是项目的pom.xml文件所在的目录。 否则,必以通过参数来指定项目的目录。
4.2. 命令参数
上面列举的只是比较通用的命令,其实很多命令都可以携带参数以执行更精准的任务。
4.2.1. -D 传入属性参数
例如:
mvn package -Dmaven.test.skip=true
以 -D 开头,将 maven.test.skip 的值设为 true ,就是告诉maven打包的时候跳过单元测试。同理,
mvn deploy-Dmaven.test.skip=true 代表部署项目并跳过单元测试。
4.2.2. -P 使用指定的Profile配置
比如项目开发需要有多个环境,一般为开发,测试,预发,正式4个环境,在pom.xml中的配置如
下:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>qa</id>
<properties>
<env>qa</env>
</properties>
</profile>
<profile>
<id>pre</id>
<properties>
<env>pre</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
</profiles>
......
<build>
<filters>
<filter>config/${env}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
......
</build>
profiles 定义了各个环境的变量 id , filters 中定义了变量配置文件的地址,其中地址中的环境
变量就是上面 profile 中定义的值, resources 中是定义哪些目录下的文件会被配置文件中定义的变量
替换。
通过maven可以实现按不同环境进行打包部署,例如:
mvn package -Pdev -Dmaven.test.skip=true
表示打包本地环境,并跳过单元测试
5. IDEA编辑器集成Maven环境
5.1. 设置Maven版本
选择 “File” —> “New Projects Settings” —> “Settings for New Projects…” —> 搜索 “Maven”
选择下载好的maven版本(目录选到bin目录的上一级目录)
设置settings.xml文件
设置好之后,选择 “Apply” 或者 “OK”
6. Maven项目的创建
6.1. 创建 Java项目
6.1.1. 新建项目
选择 “File” —> “New” —> “Project”,选择"Maven",设置JDK版本,选择maven项目的模板
设置项目的 GroupId 和 ArtifactId
检查Maven环境,选择 “Next”,和之前一样
等待项目创建,下载资源.
6.1.2. 编译项目
- 点击右上角的 "Add Configurations ",打开 “Run/Debug Configurations” 窗口
- 点击左上角的 “+” 号,选择 "Maven
- 设置编译项目的命令,如compile
- 执行编译命令,两个图标分别代表"普通模式"和"调试模式"
- 编译成功BUILD SUCCESS
6.2. 创建 Web项目
6.2.1. 创建项目
创建Web项目与创建Java项目步骤基本一致,区别在于选择 Maven模板(web项目选择
webapp).
6.2.2. 启动项目
6.2.2.1. 修改 JDK 的版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
6.2.2.2. 设置单元测试的版本(目前是删除了)
<!-- junit的版本修改为4.12 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
6.2.2.3. 删除pluginManagement标签
6.2.2.4. 添加web部署的插件
在 build 标签中添加 plugins 标签
Jetty插件 ,Tomcat插件
<build>
<finalName>maven_web</finalName>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.5.v20170502</version>
<configuration>
<httpConnector>
<port>8000</port><!-- 设置启动的端口号 -->
</httpConnector>
<webApp>
<!-- 可指定当前项目的站点名 -->
<contextPath>/test</contextPath>
</webApp>
<!-- 热部署,每10秒扫描一次 -->
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
<!-- 设置在plugins标签中 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8081</port><!-- 启动端口 默认:8080 -->
<path>/test</path><!-- 项目的站点名,即对外访问路径 -->
<uriEncoding>UTF-8</uriEncoding> <!-- 字符集编码 默认:ISO-8859-1 -->
<server>tomcat7</server> <!-- 服务器名称 -->
</configuration>
</plugin>
</plugins>
</build>
6.2.2.5. 启动项目
-
点击右上角的 "Add Configurations ",打开 “Run/Debug Configurations” 窗口
-
点击左上角的 “+” 号,选择 “Maven”
-
Jetty插件配置, Tomcat插件配置
也可以输入命令指定端口启动
jetty:run -Djetty.port=9090 # 需要将插件配置中的port标签去掉
-
点击启动图标,启动服务
-
浏览器访问http://localhost:8000/test/,http://localhost:8081/test/
Maven依赖仓库:
https://mvnrepository.com/
Tomcat7插件的命令:
https://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/plugin-info.html
7. Maven仓库的基本概念
当第一次运行Maven命令的时候, 你需要Internet链接, 因为它需要从网上下载一些文件。 那么它
从哪里下载呢? 它是从Maven默认的远程库下载的。 这个远程仓库有Maven的核心插件和可供下载的
jar文件。
对于Maven来说, 仓库只分为两类: 本地仓库和远程仓库。
当Maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用; 如果
本地没有,Maven就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。 如果本地仓库
和远程仓库都没有,Maven就会报错。
远程仓库分为三种: 中央仓库,私服, 其他公共库。
中央仓库是默认配置下,Maven下载jar包的地方。
私服是另一种特殊的远程仓库,为了节省带宽和时间,应该在局域网内架设一个私有的仓库服务器,
用其代理所有外部的远程仓库。 内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven项目目录下,没有诸如lib/这样用来存放依赖文件的目录。 当Maven在执行编译
或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下, 每个用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录。 有时
候,因为某些原因(比如c盘空间不足),需要修改本地仓库目录地址。
对于仓库路径的修改,可以通过maven 配置文件conf 目录下settings.xml来指定仓库路径
<!-- 设置到指定目录中,路径的斜杆不要写反 -->
<settings>
<localRepository>E:/m2/repository</localRepository>
</settings>
7.1. 中央仓库
由于原始的本地仓库是空的,maven必须知道至少一个可用的远程仓库,才能执行maven命令的时候
下载到需要的构件。中央仓库就是这样一个默认的远程仓库。
maven-model-builder-3.3.9.jar maven自动的 jar 中包含了一个 超级POM。定义了默认中央仓库的
位置
中央仓库包含了2000多个开源项目,接收每天1亿次以上的访问。
7.2. 私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务, 私服代理广域网上的远程仓库,供局
域网内的maven用户使用。 当maven需要下载构件时, 它去私服当中找,如果私服没有, 则从外部远
程仓库下载,并缓存在私服上, 再为maven提供。
此外,一些无法从外部仓库下载的构件也能从本地上传到私服提供局域网中其他人使用
配置方式项目pom.xml 配置
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://192.168.0.96:8081/content/groups/public/</url>
</repository>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
公司内部应该建立私服:
节省自己的外网带宽
加速maven构建
部署第三方控件
提高稳定性
降低中央仓库的负荷
7.3. 其他公共库
常用的阿里云仓库配置
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
8. Maven环境下构建多模块项目
使用maven 提供的多模块构建的特性完成maven 环境下多个模块的项目的管理与构建。
这里以四个模块为例来搭建项目,以达到通俗易懂的初衷
模块 maven_parent —– 基模块,就是常说的parent (pom)
模块 maven_dao —– 数据库的访问层,例如jdbc操作(jar)
模块 maven_service —– 项目的业务逻辑层 (jar)
模块 maven_controller —– 用来接收请求,响应数据 (war)
8.1. 创建 maven_parent 项目
选择 File —> Settings —> Project ,不选择模板
设置 GroupId 和 ArtifactId,设置项目名称及工作空间
8.2. 创建 maven_dao 模块
- 选择项目maven_parent,右键选择 New ,选择Module
- 选择Maven项目的模板(普通 Java 项目)
- 设置子模块的的 ArtifactId,设置子模块的名称及存放位置
- 设置Maven的配置
8.3. 创建 maven_service 模块
创建 maven_service 模块的步骤与 maven_dao模块一致。
8.4. 建 maven_controller 模块
创建 maven_service 模块的步骤与 maven_dao模块基本一致,只需要将第一步选择Maven模板设置
为web项目即可。(模板类型:maven-archetype-webapp)
8.5. 修改模块的配置
设置 JDK 版本
单元测试 JUnit版本
删除多余的配置
8.6. 设置模块之间的依赖
8.6.1. maven_dao
-
新建包com.whl
-
在包中创建 UserDao类
-
在类中添加方法
public void test(){
System.out.println("dao层 操作数据库 查询数据");
}
8.6.2. maven_service
- 添加maven_dao的依赖
<dependency>
<groupId>com.whl</groupId>
<artifactId>maven_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
- 在项目中添加UserService类,并添加方法
System.out.println("service层 参数校验,逻辑判断,调用数据库查询数据");
/*UserDao userDao = new UserDao();
userDao.test();*/
UserDao userDao = new UserDao();
userDao.test();
8.6.3. maven_controller
- 添加 maven_service 模块的依赖
<dependency>
<groupId>com.whl</groupId>
<artifactId>maven_service</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
- 在项目中添加UserController类,并添加方法
public void test(){
System.out.println("controller层 接受请求/返回结果");
UserService userService = new UserService();
userService.test();
}