该笔记根据网课https://www.bilibili.com/video/BV1KX4y1K7vK?p=1,与自己实际操作整理
Maven这个词可以翻译为“专家”“内行”。Maven主要服务于基于Java平台的项目构建,以来管理和项目信息管理。
无论是小型的开源类库项目,还是大型的企业级项目应用;无论是传统的瀑布开放式,开始流行的敏捷开发,Maven都能大显身手。
不管你是否意识到,构建是每一个程序员每天都在做的工作。早上来到公司,我们做的第一件事就是从源码库迁出最新的代码,然后进行单元测试,如果测试失败,会找相关的同事一起调试,修复错误代码。接着回到自己的工作上来,编写自己的单元测试产品代码。
仔细总结一下,我们会发现,除了编写源代码,我们每天有相当一部分时间花在了编译,运行单元测试,生成文档,打包和部署等繁琐且不起眼的工作上,这就是构建。如果我们现在还在手工这样做,那成本太高了,于是有人用软件的方法让这一系列工作完全自动化,使得软件的构建可以像全自动流水线一样,只需要一条简单的命令,所有的繁琐步骤都能自动完成,很快就能得到最终结果。
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编写,目前比较新型的构建工具一些初创互联网公司会使用,以后会有很大的使用空间。
Maven为java世界引入了一个新的依赖管理系统jar包管理 jar升级时修改配置文件即可。在java世界中,可以用groupId,artifactId,version组成的Coorrdination(坐标)唯一标示一个依赖。
任何基于Maven构建的项目自身也必须定义这三项属性,生成的包可以时jar包,也可以是war包或者jar包。一个典型的依赖引用 如下所示:
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
坐标属性的理解
Maven坐标为各种组件引入了秩序,任何一个组件必须明确定义自己的坐标。
groupId
定义当前Maven项目隶属的实际项目-公司名称。(jar包所在仓库路径)由于Maven中模块的概念,一次一个实际项目往往会被划分为很多模块,比如spring是一个实际项目,其对应的Maven模块会有很多,如spring-core,spring-webmvc等。
artifactId
该元素定义实际项目中的一个Maven模块-项目名,推荐的做法是使用实际项目名作为artifactId的前缀。比如:spring-bean,sping-webmvc等。
version
该元素定义Maven项目当前所处在的版本。
项目复查时 dao service controller层分离将一个项目分解为多个模块已经是很通用的一种方式
在Maven中需要顶一个parent POM作为一组module的聚合POM。在该POM中可以使用
Ant时代大家构建java项目目录时比较随意,然后通过Ant配置指定哪些属于source,哪些属于testSource等。而Maven在设计之初的理念就是Conversion over configuration(约定大于配置)。其制定了一套项目目录结构为标准的java项目结构,解决不同IDE带来的文件目录不一致问题。
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<url>http://127.0.0.1:8080/managerurl>
<server>tomcatserver>
<port>8080port>
<path>/maven01path>
<contextReloadable>truecontextReloadable>
configuration>
plugin>
JDK版本1.7及以上
下载地址http://maven.apache.org/download.cgi.
解压后把Maven的根目录配置到环境变量MAVEN_HOME, 将bin目录配置到path变量中。注:maven解压后存放的目录不要包含中文和空格
新建系统变量 MAVEN_HOME,变量值为maven解压目录中的bin目录
编辑系统变量 Path,添加变量值:%MAVEN_HOME%
${basedir}
|-- pom.xml
|-- src
| |-- main
| | `-- java
| | `-- resources
| | `-- filters
| `-- test
| | `-- java
| | `-- resources
| | `-- filters
| `-- it
| `-- assembly
| `-- site
`-- LICENSE.txt
`-- NOTICE.txt
`-- README.txt
1.1 修改默认仓库位置
打开maven目录-> conf -> settings.xml
添加仓库配置位置
<localRepository>E:/developer_tools/Maven/m2/repositorylocalRepository>
注:仓库位置改为自己本机的指定目录,"/"不要写反
1.2 更换阿里镜像,加快依赖下载
<mirror>
<id>nexus-aliyunid>
<mirrorOf>centralmirrorOf>
<name>Nexus aliyunname>
<url>http://maven.aliyun.com/nexus/content/groups/publicurl>
mirror>
注:添加到<mirrors>mirrors>标签内
作为开发利器的Maven,为我们提供了十分丰富的命令,了解maven的命令行操作并熟练运用常见的maven命令还是十分必要的,即使IDEA等工具给我们提供图形界面化工具,但其底层还是靠maven命令来驱动的。
Mavne的命令格式如下:
mvn [plugin-name]:[goal-name]
命令代表的含义:执行plugin-name插件的goal-name目标
命令 | 描述 |
---|---|
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文件所在的目录。否则,必以通过参数来指定项目的目录。
上面列举的知识比较通用的命令,其实很多命令都可以携带参数以执行更精准的任务。
例如:
mvn package -Dmaven.test.skip=true
以==-D开头,将maven.test.skip的值设置为true==,就是告诉maven打包的时候跳过单元测试,同理,mvn deploy -Dmaven.test.skip=true代表部署项目并且跳过单元测试。
比如项目开发需要多个环境,一般为开发,测试,预发,正式四个环境,在pom.xml中的配置如下:
<profiles>
<profile>
<id>devid>
<properties>
<env>devenv>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>qaid>
<properties>
<env>qaenv>
properties>
profile>
<profile>
<id>preid>
<properties>
<env>preenv>
properties>
profile>
<profile>
<id>prodid>
<properties>
<env>prodenv>
properties>
profile>
profiles>
......
<build>
<filters>
<filter>config/${env}.propertiesfilter>
filters>
<resources>
<resouce>
<directory>src/main/resourcedirectory>
<filtering>truefiltering>
resource>
resources>
profiles定义了各个环境变量的id,filters中定义了变量配置文件的地址,其中地址中的环境变量就是上面profile中定义定义的值,resources中是定义哪些目录下的文件会被配置文件中定义的变量替换。
通过maven可以实现按不同环境进行打包部署,例如:
mvn package -Pdev -Dmaven.test.skip=true
表示打包本地环境,并跳过单元测试
2.设置项目名、命名空间、groupId等
3.检查Maven环境,选择“Finish”
4.修改配置文件pom.xml
注:IDEA创建Maven项目,目录可能不全,如需要其他目录自己手动创建即可。例:创建resous目录。
1、新建目录
2、点击下方resources,即可完成创建
3、创建resources之后的目录。
1、点击右上角的“Add Configurations”,打开“Run/Debug Configurations”窗口
2.设置编译项目的命令
3.执行编译命令,两个图标分别代表“普通模式”和“调试模式”
4.编译成功
1.创建web项目与创建java项目步骤基本一致,区别在于选择Maven模板(web项目选择webapp),如图:
2.项目目录结构如下
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.11maven.compiler.source>
<maven.compiler.target>1.11maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
<pluginManagement>
...
pluginManagement>
在build标签中添加plugins标签
1.Jetty插件
<plugin>
<groupId>org.eclipse.jettygroupId>
<artifactId>jetty-maven-pluginartifactId>
<version>9.4.11.v20180605version>
<configuration>
<scanIntervalSeconds>10scanIntervalSeconds>
<webAppConfig>
<contextPath>/testcontextPath>
webAppConfig>
configuration>
plugin>
2.Tomcat插件
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>8080port>
<path>/testpath>
<uriEncoding>UTF-8uriEncoding>
<server>tomcat7server>
configuration>
plugin>
1.点击左上角的“Add Configigurations”,打开“Run/Debug Configurations”窗口
2.jetty插件配置
3.点击启动图标,启动服务
4.启动成功
浏览器访问效果
Tomcat同理,把命令换成tomcat7:run,如图所示:
当第一次运行Maven命令的时候,需要Internet链接,因为它需要从网上下载一些文件,那么它从哪里下载呢?它是从Maven默认的远程库下载的。这个远程仓库有Maven的核心插件和可供下载的jar文件。
对于Maven仓库来说,仓库只分为两类:本地仓库和远程仓库。
当Maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用;如果本地没有,Maven就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。如果本地仓库和远程仓库都没有,Maven就会报错。
远程仓库分为三种:中央仓库,私服,其它公共库。
中央仓库是默认配置下,Maven下载jar包的地方,
私服是一种特殊的远程仓库,为了节省带宽和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven项目目录下,没有诸如lib/这样用来存放依赖文件的目录。当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下,每个用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录。有时候,因为某些原因(如C盘空间不足),需要修改本地仓库目录地址。
对于仓库路径的修改,可以通过maven配置文件conf目录下的settings.xml来指定仓库路径。
<localRepository>E:/developer_tools/Maven/m2/repositorylocalRepository>
由于原始的本地仓库就是空的,maven必须知道至少一个可用的远程仓库,才能在执行maven命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库。
maven-model-builder-3.3.9.jar maven自动的jar中包含了一个超级POM。定义了默认中央仓库的位置。中央仓库包含了2000多个开源项目,接受每天1亿次以上的访问。
私服是一种特殊的远程仓库,它是假设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的maven用户使用。当maven需要下载构件时,它去私服当中找,如果私服没有,则从外部远程仓库下载,并缓存在私服上,再为maven提供。
此外,一些无法从外部仓库下载的构件也能从本地上传到私服提供局域网中供他人使用。
常用的阿里云仓库配置
<mirror>
<id>nexus-aliyunid>
<mirrorOf>centralmirrorOf>
<name>Nexus aliyunname>
<url>http://maven.aliyun.com/nexus/content/groups/publicurl>
mirror>
使用maven提供的多模块构建的特性完成maven环境下多个模块的项目的管理与构建。
这里以四个模块为例来搭建项目,以达到通俗易懂的初衷
模块 maven_parent -- 基模块,就是常说的parent (pom)
模块 maven_dao -- 数据库的访问层,例如jdbc从操作(jar)
模块 maven_service -- 项目的业务逻辑层(jar)
模块 maven_controller -- 用来接收请求,响应数据(war)
1.选择File-> New -> Project
2.设置相关信息
1.选择项目maven_parent,右键选择New,选择Module
2.选择Maven项目的模板(普通Java项目)
3.设置子模块的相关信息
创建maven_service的步骤与maven_dao模块一致。
创建maven_controller模块的步骤与maven_dao模块基本一致,只需要将第一步的Maven模板设置为web项目即可。(模板类型:maven-archetype-webapp)
1.新建包
2.在包中创建UserDao类
3.在类中添加方法
public class UserDao {
public static void testDao(){
System.out.println("UserDao test.....");
}
}
1.添加maven_dao的依赖
<dependency>
<groupId>com.xxxxgroupId>
<artifactId>maven_daoartifactId>
<version>1.0-SNAPSHOTversion>
<scope>compilescope>
dependency>
2.在项目中添加UserService类,并添加方法
public class UserService {
public static void testService(){
System.out.println("UserService Test....");
//调用UserDao的方法
UserDao.testDao();
}
}
1.添加maven_service的依赖
<dependency>
<groupId>com.xxxxgroupId>
<artifactId>maven_serviceartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
2.添加Servlet的依赖
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
3.新建Java类,继承HttpServlet类并重写service方法
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("UserServlett Test...");
//调用maven_service模块的方法
UserService.testService();
}
}
4.添加Tomcat插件
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<path>/webpath>
<uriEncoding>UTF-8uriEncoding>
<server>tomcat7server>
configuration>
plugin>
如果启动项目失败,就把maven_parent项目install一下
6.启动成功
对于企业级项目,无论是进行本地测试,还是测试环境测试以及最终的项目上线,都会涉及项目的打包操作。对于每个环节下的项目打包,对应的项目所需要的配置资源会有所差别,实现打包的方式有很多种,可以通过ant,或者通过idea自带的打包功能实现项目打包,但当项目很大并且需要的外界配置很多时,此时打包的配置就会异常复杂,对于maven项目,我们可以通过pom.xml配置的方式来实现打包时的环境选择,相比较其他形式打包工具,通过maven只需要通过简单的配置,就可以轻松完成不同环境下的项目的整体打包。
比如下面这样一个项目,项目中配置了不同环境下所需要的配置文件,这时候需要完成不同环境下的打包操作,此时通过修改pom.xml如下:
使用idea创建目录,目录结构可能会确实,需要手动添加对应的目录。
1.添加java源文件夹
2.添加resources文件夹
3.添加对应的文件夹目录,添加不同环境下对应的配置文件。(本地环境、测试环境、正式环境)
<profiles>
<profile>
<id>devid>
<properties>
<env>devenv>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>testid>
<properties>
<env>testenv>
properties>
profile>
<profile>
<id>productid>
<properties>
<env>productenv>
properties>
profile>
profiles>
<resources>
<resource>
<directory>src/main/resources/${env}directory>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
<include>**/*.propertiesinclude>
<include>**/*.tldinclude>
includes>
<filtering>falsefiltering>
resource>
resources>