沉淀再出发:Maven的使用和规范

Posted 精心出精品

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了沉淀再出发: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} "$@"
View Code

 

    然后我们在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 构建项目(核心:常用),包括以下阶段
    1. validate
    2. initialize
    3. generate-sources
    4. process-sources
    5. generate-resources
    6. process-resources    :复制和处理资源文件到target目录,准备打包;
    7. compile    :编译项目的源代码;
    8. process-classes
    9. generate-test-sources
    10. process-test-sources
    11. generate-test-resources
    12. process-test-resources
    13. test-compile    :编译测试源代码;
    14. process-test-classes
    15. test    :运行测试代码;
    16. prepare-package
    17. package    :打包成jar或者war或者其他格式的分发包;
    18. pre-integration-test
    19. integration-test
    20. post-integration-test
    21. verify
    22. install    :将打好的包安装到本地仓库,供其他项目使用;
    23. 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,在编译阶段需要引用,而在服务器

以上是关于沉淀再出发:Maven的使用和规范的主要内容,如果未能解决你的问题,请参考以下文章

沉淀再出发:jvm的本质

沉淀再出发:redis的安装和使用

沉淀再出发:openstack初探

沉淀再出发:jvm的本质

沉淀再出发:如何在eclipse中查看java的核心代码

沉淀再出发:java中注解的本质和使用