沉淀,再出发:Maven的使用和规范
沉淀,再出发:Maven的使用和规范
一、前言
Maven作为项目管理工具,在一个大型项目开发的每个阶段都有着很大的用处,为什么需要这个东西呢,还是为了消除不确定性,统一化管理,正如我们做的每一件事其实都是为了消除不确定性一样,知道的越多不确定性就越少,在程序开发之中大家分工协作,每个人可能使用不同的插件、包以及其他工具,这些东西大多是从网上下载的,要知道软件都是有版本的,有的功能可能在这个版本没有,下个版本却有了,那么如果大家虽然都使用同一个软件,但是用的是不一样的版本的,在项目后期的合并之中造成的麻烦是非常严重的,要怎么办呢?!当然我们可以提前定义好要使用的工具以及版本号,可是还是有人会忘记或者搞错,只要一个人的错了,那么上传到Github等项目托管平台上,其他人pull下来的时候就糟糕了,会因为相互混合而导致项目运行失败,这样的责任谁去负责呢?!于是Maven这个神器就应用而生了,它的出现就是为了统一风格、统一使用的工具、统一一切可以规范的。这种统一对于我们的项目意义深远,更加了不起的是,它能够从本地仓库和中央仓库之中将这些统一标准的软件自动下载下来,这就极大的将程序员从各种复杂的环境配置中解放了出来,可以直接将精力和时间放到业务需求以及代码的开发上,因此,程序员如果不懂得Maven、Github这类项目管理工具应该说不能算是程序员,只能算是初学者或者打酱油的。
那么在信息爆炸的时代,到底需要学习maven的哪些知识呢?要学到什么程度?本文我们就来探讨一下。
二、从基础开始
首先我们需要安装被配置java的环境,之后才能使用maven。
2.1、下载
最基础的就是安装了,我们以windows为例来说明,首先从官网上下载Maven这个软件。养成好的习惯,下载最新的、最稳定的或者最适合的版本,并且使用SHA1算法验证一下下载的是不是正确的,可以看到验证成功。
2.2、安装配置
接下来就是安装和配置了,maven比较简单,不用向注册表中写入内容就可以,直接解压到一个目录下就等于安装了,此时就可以使用了,但是每一次都要切换到这个目录下的.\bin目录非常的麻烦,因此有必要配置一下环境变量,将该目录写入到PATH环境变量中去,至于有的上面再加一个变量名叫做M2_HOME=“Maven文件目录”的也是为了规范化,理解了本质的我们是不用这样做的,直接增加就可以。一定要是bin目录,然后才能使用这个文件夹下的软件功能。
在这里我们找到了经常使用的工具mvn,打开可以看到里面的代码正是为了我们输入的命令服务的。
mvn代码:
#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ----------------------------------------------------------------------------- # Apache Maven Startup Script # # Environment Variable Prerequisites # # JAVA_HOME Must point at your Java Development Kit installation. # MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. # MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. # ----------------------------------------------------------------------------- if [ -z "$MAVEN_SKIP_RC" ] ; then if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi if [ -f "$HOME/.mavenrc" ] ; then . "$HOME/.mavenrc" fi fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; mingw=false; case "`uname`" in CYGWIN*) cygwin=true;; MINGW*) mingw=true;; esac ## resolve links - $0 may be a link to Maven's home PRG="$0" # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done saveddir=`pwd` MAVEN_HOME=`dirname "$PRG"`/.. # make it fully qualified MAVEN_HOME=`cd "$MAVEN_HOME" && pwd` cd "$saveddir" # For Cygwin, ensure paths are in Unix format before anything is touched if $cygwin ; then [ -n "$MAVEN_HOME" ] && MAVEN_HOME=`cygpath --unix "$MAVEN_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi # For MinGW, ensure paths are in Unix format before anything is touched if $mingw ; then [ -n "$MAVEN_HOME" ] && MAVEN_HOME=`(cd "$MAVEN_HOME"; pwd)` [ -n "$JAVA_HOME" ] && JAVA_HOME=`(cd "$JAVA_HOME"; pwd)` # TODO classpath? fi if [ -z "$JAVA_HOME" ] ; then JAVACMD=`which java` else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then echo "The JAVA_HOME environment variable is not defined correctly" >&2 echo "This environment variable is needed to run this program" >&2 echo "NB: JAVA_HOME should point to a JDK not a JRE" >&2 exit 1 fi CLASSWORLDS_JAR=`echo "${MAVEN_HOME}"/boot/plexus-classworlds-*.jar` CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher # For Cygwin, switch paths to Windows format before running java if $cygwin ; then [ -n "$MAVEN_HOME" ] && MAVEN_HOME=`cygpath --path --windows "$MAVEN_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"` [ -n "$CLASSWORLDS_JAR" ] && CLASSWORLDS_JAR=`cygpath --path --windows "$CLASSWORLDS_JAR"` fi # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { ( basedir=`find_file_argument_basedir "$@"` wdir="${basedir}" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi wdir=`cd "$wdir/.."; pwd` done echo "${basedir}" ) } find_file_argument_basedir() { ( basedir=`pwd` found_file_switch=0 for arg in "$@"; do if [ ${found_file_switch} -eq 1 ]; then if [ -d "${arg}" ]; then basedir=`cd "${arg}" && pwd -P` elif [ -f "${arg}" ]; then basedir=`dirname "${arg}"` basedir=`cd "${basedir}" && pwd -P` if [ ! -d "${basedir}" ]; then echo "Directory ${basedir} extracted from the -f/--file command-line argument ${arg} does not exist" >&2 exit 1 fi else echo "POM file ${arg} specified with the -f/--file command line argument does not exist" >&2 exit 1 fi break fi if [ "$arg" = "-f" -o "$arg" = "--file" ]; then found_file_switch=1 fi done echo "${basedir}" ) } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then echo "`tr -s '\r\n' ' ' < "$1"`" fi } MAVEN_PROJECTBASEDIR="${MAVEN_BASEDIR:-`find_maven_basedir "$@"`}" MAVEN_OPTS="`concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config"` $MAVEN_OPTS" # For Cygwin, switch project base directory path to Windows format before # executing Maven otherwise this will cause Maven not to consider it. if $cygwin ; then [ -n "$MAVEN_PROJECTBASEDIR" ] && MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` fi export MAVEN_PROJECTBASEDIR # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS exec "$JAVACMD" \ $MAVEN_OPTS \ $MAVEN_DEBUG_OPTS \ -classpath "${CLASSWORLDS_JAR}" \ "-Dclassworlds.conf=${MAVEN_HOME}/bin/m2.conf" \ "-Dmaven.home=${MAVEN_HOME}" \ "-Dlibrary.jansi.path=${MAVEN_HOME}/lib/jansi-native" \ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${CLASSWORLDS_LAUNCHER} "$@"
然后我们在cmd中测试一下,安装和配置成功,当然了,我们必须先安装Java的环境,maven的运行需要java的支持。
2.3、牛刀小试
我们用最土的办法,一个个的创建符合Maven格式的文件夹,然后再来测试:
pom.xml:这个文件是我们和maven打交道的一个主要的渠道,通过对pom.xml进行编辑,可以实现我们之前说的定义包、版本、依赖等信息,并且能够让maven从中央仓库去下载。这里要注意红色部分,这些东西是我们自己编写的程序的ID或者叫做坐标,可以唯一标定我们的程序。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 5 <groupId>maven.zyr</groupId> 6 <artifactId>maven01</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 9 <dependencies> 10 <dependency> 11 <groupId>junit</groupId> 12 <artifactId>junit</artifactId> 13 <version>4.12</version> 14 </dependency> 15 16 </dependencies> 17 </project>
后面是包名:
1 package zyr.maven; 2 3 public class Hello{ 4 public String sayHello(){ 5 return "Hello Maven"; 6 } 7 }
另一个目录:
1 package zyr.maven; 2 3 import org.junit.*; 4 5 public class TestClass{ 6 @Test 7 public void testHello(){ 8 System.out.println(new Hello().sayHello()); 9 } 10 }
于是整个结构是这样:
到了这里我们就可以使用maven来编译和测试了:
mvn compile
可以看到使用mvn编译成功,得到了我们想要的结果,并且生成了编译之后的目标文件,这样我们就可以测试了。
使用mvn test我们测试一下程序的执行结果:
mvn test
可以看到测试成功得到了想要的结果。、
2.4、个人仓库
之后我们可以将这个程序放到个人仓库之中,使用
1 mvn install
但是此时这个仓库默认是放在C盘的,如果以后装机的时候不小心给忘记了,那么这些东西就没有了,非常的麻烦,那我们需要怎么办呢,在maven的安装目录之中有一个conf文件夹,里面有一个setting.xml文件,我们只需要修改这个文件的一点配置就可以了。将localRepository修改成我们想要存储的位置就可以了。
之后我们可以看到已经按照我们的需要存放了:
2.5、自动生成目录
每次都自己创建文件夹是一项非常粗笨的工作,因此肯定有插件可以帮我们实现的,那就是:
mvn archetype:generate
我们在新的文件之中使用这个命令,可以看到经过一段时间的下载之后,出现了交互界面,我们写入自己需要定义的包名、程序名、版本号等坐标之后,这个插件自动为我们生成了这些东西,从此我们再也不用手工去忙碌了。
2.6、Maven的坐标、常用命令以及生命周期
坐标:maven 的所有构件均通过坐标进行组织和管理。maven 的坐标通过 5 个元素进行定义,其中 groupId、artifactId、version 是必须的,packaging 是可选的(默认为jar),classifier 是不能直接定义的。
maven使用groupId、artifactId、version唯一确定坐标,每个坐标都唯一的指向一个maven项目:
包名应与groupId+artifactId相吻合 groupId:项目组织唯一的标识符,一般为反写的公司网址+项目名,跟 Java 包名类似,通常与域名反向一一对应。 artifactId:项目的唯一的标识符,一般为项目名+模块名,定义当前 Maven 项目的一个模块,默认情况下,Maven 生成的构件,其文件名会以 artifactId 开头,如 hibernate-core-3.6.5.Final.jar。 version:版本号 x.x.x+版本类型 第一个x表示大版本号 第二个x表示分支版本号 第三个x表示小版本号(可省略) 常见版本类型: snapshot快照 alpha内部测试 beta公测 release稳定 GA正式发布
packaging:定义项目打包方式,如 jar,war,pom,zip ……,默认为 jar。
classifier:定义项目的附属构件,如 hibernate-core-3.6.6.Final-sources.jar,hibernate-core-3.6.6.Final-javadoc.jar,其中 sources 和 javadoc 就是这两个附属构件的 classifier。classifier 不能直接定义,通常由附加的插件帮助生成。
常用命令:
mvn -v 查看maven版本及其他相关信息 compile 编译maven项目,并生成target文件夹 test 运行test目录下的测试文件,即测试 package 将项目打包,默认打包为jar格式,也可以打包成war格式用于服务器运行 install 将打包的jar文件安装到maven本地仓库(仓库后面会详细介绍) clean 删除targert,相当于清除缓存
生命周期:
多个生命周期之间相互独立。每个生命周期含有多个阶段,阶段按顺序执行,运行后阶段时,前阶段会自动执行。 完整的项目构建构成包括: 清理、编译、测试、打包、集成测试、验证、部署 clean 清理项目,包括以下阶段: pre-clean 执行清理前 clean 清理上一次构建生成的所有文件 post-clean 执行清理后的文件
default 构建项目(核心:常用),包括以下阶段
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources :复制和处理资源文件到target目录,准备打包;
- compile :编译项目的源代码;
- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources
- test-compile :编译测试源代码;
- process-test-classes
- test :运行测试代码;
- prepare-package
- package :打包成jar或者war或者其他格式的分发包;
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install :将打好的包安装到本地仓库,供其他项目使用;
- deploy :将打好的包安装到远程仓库,供其他项目使用;
其中主要包括这几个步骤:
compile 编译 test 测试 packeage 打包 install 安装
site 生成项目站点,根据pom中信息生成项目站点,包括以下阶段 pre-site 在生成项目站点前要完成的工作 site生成项目的站点文档 post-site在生成项目站点后要完成的工作 site-deploy发布生成的站点到服务器上
2.7、插件
可以说maven本身的源程序并不是很多,大部分功能都是来自于自己的插件,可以将插件绑定到生命周期的某个阶段,从而在这个阶段运行插件,生成相应的东西,比如我们经常使用的mvn package将程序编译测试并且打包,如果将打包源代码的插件绑定到这个阶段就能在打包的时候生成源代码的打包文件,非常的方便。
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-source-plugin</artifactId> 6 <version>2.2.1</version> 7 <executions> 8 <execution> 9 <id>attach-source</id> 10 <phase>package</phase><!-- 要绑定到的生命周期的阶段 --> 11 <goals> 12 <goal>jar-no-fork</goal><!-- 要绑定的插件的目标 --> 13 </goals> 14 </execution> 15 </executions> 16 </plugin> 17 </plugins> 18 </build>
当然了这些插件在本身就有默认的和生命周期的绑定,不同的项目有jar、war、pom等不同的打包方式,因此对应的有不同的绑定关系,其中针对default生命周期的jar包打包方式的绑定关系如下:
同时插件还可以动态地配置,不是一成不变的,这对我们的使用来说也是非常方便的,比如配置编译的时候使用JDK1.7版本的环境。
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-compiler-plugin</artifactId> 4 <configuration> 5 <source>1.7</source> 6 <target>1.7</target> 7 </configuration> 8 </plugin>
比如我们的平台是JDK1.8的,因此就会提示警告,但是这里注意没有报错。
同时插件也存储在仓库之中,在需要使用的时候会自动下载下来的。
2.8、pom.xml中常用标签介绍以及maven依赖
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <!-- 当前pom的版本--> 4 <modelVersion>4.0.0</modelVersion> 5 6 <!--坐标--> 7 <groupId>cn.edu</groupId> 8 <artifactId>maven04</artifactId> 9 <version>0.0.1-SNAPSHOT</version> 10 <!-- 默认是jar,其他war zip pom等 --> 11 <packaging>jar</packaging> 12 13 <!--项目描述名 --> 14 <name>maven04</name> 15 <!-- 项目地址 --> 16 <url>http://maven.apache.org</url> 17 18 <!-- 配置参数 --> 19 <properties> 20 <!-- 这里配置项目编译编码为UTF-8--> 21 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 22 </properties> 23 24 <!-- 开发人员信息 --> 25 <developers></developers> 26 <!-- 项目描述 --> 27 <description></description> 28 <!-- 许可信息 --> 29 <licenses></licenses> 30 <!-- 组织信息 --> 31 <organization></organization> 32 <!-- 依赖集,用于配置依赖 --> 33 <dependencies> 34 <dependency> 35 <groupId>junit</groupId> 36 <artifactId>junit</artifactId> 37 <version>3.8.1</version> 38 39 <!-- 依赖范围:这个jar包只在范围内生效,范围外引用会报错,这里让junit只在test时被依赖。 40 其他一些情况,如:servlet-api.jar,在编译阶段需要引用,而在服务器运行阶段则不需要引用,就可以使用scope--> 41 <scope>test</scope> 42 43 <!-- 默认为false,子项目将会继承,true时子项目需要显式引用 --> 44 <optional>false</optional> 45 46 <!-- 排除依赖列表:用于去除传递依赖等--> 47 <exclusions> 48 <exclusion></exclusion> 49 </exclusions> 50 51 52 </dependency> 53 </dependencies> 54 55 <!-- 依赖管理 56 为依赖进行统一管理,如果在父项目中声明此标签时,在子项目中不需声明,确保父子项目依赖版本一致; 57 如子项目需要不同版本的依赖,只需在子项目中进行声明即可,将会覆盖父项目中的声明。 58 --> 59 <!-- 60 <dependencyManagement> 61 <dependencies> 62 <dependency></dependency> 63 </dependencies> 64 </dependencyManagement> 65 --> 66 67 <!--配置构建时的属性--> 68 <build> 69 <plugins></plugins> 70 </build> 71 72 <!-- 指定父模块 --> 73 <!-- <parent></parent> --> 74 75 <!-- 用于聚合编译多个maven模块 --> 76 <modules></modules> 77 </project>
maven依赖(范围、传递、冲突、排除、归类):
执行不同的 Maven 命令(mvn package,mvn test,mvn install ……),会使用不同的 classpath,Maven 对应的有三套 classpath:编译classpath、测试classpath,运行classpath。scope 选项的值,决定了该依赖构件会被引入到哪一个 classpath 中。
范围:maven中提供了三种classpath:编译、测试、运行 scope标签 -compile 默认,编译测试运行均有效,会传递 -provided 在编译和测试时有效,如servletAPI可以加入,不传递 -runtime 在测试和运行时有效,如JDBCAPI可以加入 -test 在测试时有效,如junit可以加入 -system 在编译和测试时有效,与本机系统相关联,移植性差,在系统中以外部jar包的形式引入,不会在仓库中查找 -import 导入,只能用在dependecyManagement中,表示从其他pom中导入dependecy的配置 传递: 如果C依赖B,B依赖A,那么C→B→A,那么此时C也会依赖A且会包含A中的依赖,这就是传递依赖。消除传递依赖:需要使用<exclusions>
冲突:
当多个传递性依赖中有对同一构件不同版本的依赖时,如何解决呢?
短路径优先:假如有以下依赖:A -> B -> C ->X(版本 1.0) 和 A -> D -> X(版本 2.0),则优先解析较短路径的 X(版本 2.0);
先声明优先:若路径长度相同,则谁先声明,谁被解析。
依赖排除:
针对依赖冲突中的“短路径优先”,如果我们想使用长路径的依赖怎么办呢?
这时可以使用依赖排除 <exclusions> 元素,显示排除短路径依赖。在非冲突的情况下,这种方法同样有效。
依赖归类:
通常在项目中,我们会同时依赖同一个构件的不同模块,如 spring-orm-3.2.0,spring-context-3.2.0,且多个模块版本相同,
为了维护和升级方便,我们可以对其同一管理,这时可以使用到 Maven 属性,类似于变量的概念。
<properties> <springframework.version>3.2.0.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> </dependencies>
2.9、聚合和继承
这里和我们设计模式之中的聚合和继承是很类似的,只不过把主体从类变成了pom.xml文件而已。
聚合:在一个项目中,分模块使用了maven,那么可能在这个项目中会有五六个,或者更多的maven项目存在。如果此时需要编译或测试要怎么办呢,进入每个maven项目中进行mvn compile么,那就要执行五六次的compile命令,十分繁琐,这里就可以用maven的聚合来解决这个问题。
现有ABC三个工程,那么我们使用一个新的工程D,来聚合他们,以后只要对D进行编译即可对三个工程同时进行编译。使用module标签进行聚合:
1 <modules> 2 <!--这里的路径是基于D项目的pom.xml路径,module标签内为指向其他项目的pom文件的路径 3 A、B、C、D项目在同一个文件夹内,那么从D内的pom中,通过../项目名,来找到其他项目的pom.xml--> 4 <module>../A</module> 5 <module>../B</module> 6 <module>../C</module> 7 </modules>
继承:另一种情形,如果多个maven项目具有相同的依赖时或配置时,那么应该如何处理呢?这里就用到继承的概念,在maven中使用<parent>标签来进行继承,比如建立一个项目,命名为parent,在parent的pom文件声明一个common-io的依赖,不过这里用到了dependencyManagement:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 5 <groupId>cn.edu</groupId> 6 <artifactId>parent</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 <packaging>pom</packaging> 9 10 <name>parent</name> 11 <url>http://maven.apache.org</url> 12 13 <properties> 14 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 15 </properties> 16 17 <dependencies> 18 <dependency> 19 <groupId>junit</groupId> 20 <artifactId>junit</artifactId> 21 <version>4.12</version> 22 <scope>test</scope> 23 </dependency> 24 </dependencies> 25 26 <dependencyManagement> 27 <!-- 在这里声明的依赖可以被子项目继承引用 --> 28 <dependencies> 29 <dependency> 30 <groupId>commons-io</groupId> 31 <artifactId>commons-io</artifactId> 32 <version>2.4</version> 33 </dependency> 34 </dependencies> 35 </dependencyManagement> 36 </project>
在子项目中,配置继承parent并使用parent中的common-io版本:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 5 6 <groupId>cn.edu</groupId> 7 <artifactId>B</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>B</name> 12 <url>http://maven.apache.org</url> 13 14 <properties> 15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 16 </properties> 17 18 <!-- 在parent标签中使用父项目的坐标进行配置 --> 19 <parent> 20 <groupId>cn.edu</groupId> 21 <artifactId>parent</artifactId> 22 <version>0.0.1-SNAPSHOT</version> 23 </parent> 24 25 <dependencies> 26 <!-- 此处使用依赖时,就不需声明版本 --> 27 <dependency> 28 <groupId>commons-io</groupId> 29 <artifactId>commons-io</artifactId> 30 </dependency> 31 32 <dependency> 33 <groupId>junit</groupId> 34 <artifactId>junit</artifactId> 35 <version>4.12</version> 36 <scope>test</scope> 37 </dependency> 38 </dependencies> 39 </project>
三、将Maven程序放到Eclipse或者Myeclipse之中使用
到了这里我们才开始蹒跚学步第一步,前面的都是为了我们之后的使用和操作积累基础的,那我们就来看看这个最常用的操作吧。
3.1、创建maven project
更改配置,使用我们自己的maven,不然myeclipse(我这里使用的是2014版)会使用默认的,内置的maven。
甚至我们还可以增加环境变量,不过对于已经在windows中配置过的,我们可以不用再次配置。
到了这里我遇到了一个问题,这个问题导致我昨天几乎花了四五个小时还是一筹莫展,那就是我也按照网上的说明设置了这些参数,并且按照别人的创建方法创建了maven工程,选的是quickstart的,然后自定义了坐标,结果创建之后就是错误,有错误不可怕,我就一直在修复错误了,结果却没有一点改善的样子,我尝试了很多的方式一直都是这样,再加上这个Myeclipse2014非常的占用内存,让我真的很难接受,就这样白白的浪费了时间,糟蹋了心情。由此可以看到一个好的IDE的重要性,可以让我们把主要的精力放到自己关心的事情上面,而不是一直在这里调错,改错,结果改完这个错误那个错误又出现了。后来我暂时的放下了继续往下做的念头,到了今天,心情渐渐好转,我又安装了Myeclipse2017这个算是最新版的了,可以说是与时俱进的,当时的2014版,对maven的支持可以说是有很大的缺陷的,才导致了我们一直在这些傻瓜的错误上浪费时间,当我装上了2017版本之后,一切都是那样的简单了,这就是好的IDE为我带来的福利,这个2017版本不用配置maven环境就可以支持maven,因为它的内部早就集成了maven的环境,并且也集成了Tomcat的环境,因此这两个东西不用配置就可以使用了呢,多么的强大呀,到这里我想说的是2014也集成了这些东西,可是真的很垃圾,maven一用就容易错,Tomcat更是时不时的挂掉。因此,下面我们使用Myeclipse2017来讲解。
在myeclipse2017中,我们不用配置maven环境,系统自带的环境,我们可以查看是3.3.9的版本,可以看到embedded这个字样,就是嵌入在2017内部的意思。然后我们不用任何配置,直接创建maven project。
我们使用mvn package命令来运行:
可以看到已经运行成功:
那么我们也可以根据自己的需要改成我们以前安装的maven版本:
在1的地方我们随便命名就可以,在2的地方,我们都不用填,相比于以前要写一串环境变量的,这个IDE特别的强大。
然后我们再次运行:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------< com.zyr.net:MyTest1 >------------------------- [INFO] Building MyTest1 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:3.0.0:clean (default-clean) @ MyTest1 --- [INFO] Deleting D:\workspace\MyTest1\target [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ MyTest1 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\workspace\MyTest1\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ MyTest1 --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\workspace\MyTest1\target\classes [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ MyTest1 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\workspace\MyTest1\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ MyTest1 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ MyTest1 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\workspace\MyTest1\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ MyTest1 --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\workspace\MyTest1\target\test-classes [INFO] [INFO] --- maven-surefire-plugin:2.20.1:test (default-test) @ MyTest1 --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.zyr.net.MyTest1.AppTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.094 s - in com.zyr.net.MyTest1.AppTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ MyTest1 --- [INFO] Building jar: D:\workspace\MyTest1\target\MyTest1-0.0.1-SNAPSHOT.jar [INFO] [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ MyTest1 --- [INFO] Installing D:\workspace\MyTest1\target\MyTest1-0.0.1-SNAPSHOT.jar to D:\zyrLocalRepository\com\zyr\net\MyTest1\0.0.1-SNAPSHOT\MyTest1-0.0.1-SNAPSHOT.jar [INFO] Installing D:\workspace\MyTest1\pom.xml to D:\zyrLocalRepository\com\zyr\net\MyTest1\0.0.1-SNAPSHOT\MyTest1-0.0.1-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.799 s [INFO] Finished at: 2018-07-04T11:05:06+08:00 [INFO] ------------------------------------------------------------------------
可以看到和我们在命令行的结果是一致的,并且也按照我们的意愿存储在了我们指定的文件夹。
我们将文件进行更改:
1 package com.zyr.net.MyTest1; 2 3 public class App 4 { 5 public String sayHello( ) 6 { 7 return "Hello zyr!" ; 8 } 9 }
1 package com.zyr.net.MyTest1; 2 3 import org.junit.Test; 4 5 6 public class AppTest 7 { 8 @Test 9 public void myTest() 10 { 11 System.out.println("运行结果为:"+new App().sayHello()); 12 } 13 }
运行mvn test命令,这里有两种方法,一种是直接运行->test,另一种是使用命令test,可以看到成功得到结果。
3.2、创建java项目然后使用maven
然后我们尝试一下最常用的方式,这种方式抛弃了maven的代码结构,我们首先创建java project,然后在src的上一层我们创建一个pom.xml,里面使用我们项目需要的依赖,如图所示,然后我们使用项目->右键->config中的转换成maven项目,之后就会自动增加依赖了,这样之后我们按照自己的需要编写java程序就可以了,然后运行的时候我们不使用maven来做,而是直接使用java的运行方式,使用这种方法,我们还可以将Tomcat的某些功能引入进来,构成我们的项目矿建,这样就不用拘泥于maven的格式同样能够使用maven来给我们的项目带来实惠了。
最后再提供一下依赖的查找网址:http://mvnrepository.com/、https://repository.sonatype.org/、http://search.maven.org/
四、总结
通过我们系统的学习,可以知道maven的原理,基本的构成,其中最重要的就是pom.xml文件的编写了,如何实现依赖的组合,同时在大型项目中又如何避免以来带来的冲突等问题,以及如何寻找我们需要的依赖,maven的生命周期,基本的使用方法,clean,compile,test,package,install等原理以及背后做的事情,通过这些学习我们将maven引入了myeclipse之中,更加的接近工程化开发方法,并且讲解了如何使用,通过这样的学习,我们关于maven的使用也算是渐入佳境了,需要注意的是我们最好使用最新版的myeclipse2017这样可以帮助我们避免很多没有理由的错误。