第一次知道MAVEN是在2008年,当时想分析geoserver这个开源项目,发现该项目采用了maven进行项目管理,当时粗略的学习了一下。真正在工作中使用是在09年下半年,个人感觉使用起来还是非常好,特别是在jar包的管理上规范了很多,而且项目中添加jar包或下源码都十分方便,但是团队中的成员总是有个别人使用得很痛苦,不是这个找不到,就是发布项目出问题,鉴于此,我动了分析源码的念头。
先通过svn从 https://svn.apache.org/repos/asf/maven/maven-3/trunk 上checkout了一份源码。项目结构如下图:
由于使用maven基本是通过其bin目录下的mvn.bat命令为入口,所以有必要先了解下该批处理文件,把多余的注释去掉后,该文件显示如下:
1 @echo off 2 @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 3 @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 4 5 @REM set %HOME% to equivalent of $HOME 6 if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 7 8 @REM Execute a user defined script before this one 9 if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 10 if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 11 :skipRcPre 12 13 set ERROR_CODE=0 14 15 @REM set local scope for the variables with windows NT shell 16 if "%OS%"=="Windows_NT" @setlocal 17 if "%OS%"=="WINNT" @setlocal 18 19 @REM ==== START VALIDATION ==== 20 if not "%JAVA_HOME%" == "" goto OkJHome 21 22 echo. 23 echo ERROR: JAVA_HOME not found in your environment. 24 echo Please set the JAVA_HOME variable in your environment to match the 25 echo location of your Java installation 26 echo. 27 goto error 28 29 :OkJHome 30 if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome 31 32 echo. 33 echo ERROR: JAVA_HOME is set to an invalid directory. 34 echo JAVA_HOME = "%JAVA_HOME%" 35 echo Please set the JAVA_HOME variable in your environment to match the 36 echo location of your Java installation 37 echo. 38 goto error 39 40 :chkMHome 41 if not "%M2_HOME%"=="" goto valMHome 42 43 if "%OS%"=="Windows_NT" SET "M2_HOME=%~dp0.." 44 if "%OS%"=="WINNT" SET "M2_HOME=%~dp0.." 45 if not "%M2_HOME%"=="" goto valMHome 46 47 echo. 48 echo ERROR: M2_HOME not found in your environment. 49 echo Please set the M2_HOME variable in your environment to match the 50 echo location of the Maven installation 51 echo. 52 goto error 53 54 :valMHome 55 56 :stripMHome 57 if not "_%M2_HOME:~-1%"=="_\" goto checkMBat 58 set "M2_HOME=%M2_HOME:~0,-1%" 59 goto stripMHome 60 61 :checkMBat 62 if exist "%M2_HOME%\bin\mvn.bat" goto init 63 64 echo. 65 echo ERROR: M2_HOME is set to an invalid directory. 66 echo M2_HOME = "%M2_HOME%" 67 echo Please set the M2_HOME variable in your environment to match the 68 echo location of the Maven installation 69 echo. 70 goto error 71 @REM ==== END VALIDATION ==== 72 73 :init 74 @REM Decide how to startup depending on the version of windows 75 76 @REM -- Windows NT with Novell Login 77 if "%OS%"=="WINNT" goto WinNTNovell 78 79 @REM -- Win98ME 80 if NOT "%OS%"=="Windows_NT" goto Win9xArg 81 82 :WinNTNovell 83 84 @REM -- 4NT shell 85 if "%@eval[2+2]" == "4" goto 4NTArgs 86 87 @REM -- Regular WinNT shell 88 set MAVEN_CMD_LINE_ARGS=%* 89 goto endInit 90 91 @REM The 4NT Shell from jp software 92 :4NTArgs 93 set MAVEN_CMD_LINE_ARGS=%$ 94 goto endInit 95 96 :Win9xArg 97 @REM Slurp the command line arguments. This loop allows for an unlimited number 98 @REM of agruments (up to the command line limit, anyway). 99 set MAVEN_CMD_LINE_ARGS= 100 :Win9xApp 101 if %1a==a goto endInit 102 set MAVEN_CMD_LINE_ARGS=%MAVEN_CMD_LINE_ARGS% %1 103 shift 104 goto Win9xApp 105 106 @REM Reaching here means variables are defined and arguments have been captured 107 :endInit 108 SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 109 110 @REM -- 4NT shell 111 if "%@eval[2+2]" == "4" goto 4NTCWJars 112 113 @REM -- Regular WinNT shell 114 for %%i in ("%M2_HOME%"\boot\plexus-classworlds-*) do set CLASSWORLDS_JAR="%%i" 115 goto runm2 116 117 @REM The 4NT Shell from jp software 118 :4NTCWJars 119 for %%i in ("%M2_HOME%\boot\plexus-classworlds-*") do set CLASSWORLDS_JAR="%%i" 120 goto runm2 121 122 @REM Start MAVEN2 123 :runm2 124 set CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 125 %MAVEN_JAVA_EXE% %MAVEN_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 126 if ERRORLEVEL 1 goto error 127 goto end 128 129 :error 130 if "%OS%"=="Windows_NT" @endlocal 131 if "%OS%"=="WINNT" @endlocal 132 set ERROR_CODE=1 133 134 :end 135 @REM set local scope for the variables with windows NT shell 136 if "%OS%"=="Windows_NT" goto endNT 137 if "%OS%"=="WINNT" goto endNT 138 139 @REM For old DOS remove the set variables from ENV - we assume they were not set 140 @REM before we started - at least we don't leave any baggage around 141 set MAVEN_JAVA_EXE= 142 set MAVEN_CMD_LINE_ARGS= 143 goto postExec 144 145 :endNT 146 @endlocal & set ERROR_CODE=%ERROR_CODE% 147 148 :postExec 149 150 if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 152 :skipRcPost 153 154 @REM pause the batch file if MAVEN_BATCH_PAUSE is set to 'on' 155 if "%MAVEN_BATCH_PAUSE%" == "on" pause 156 157 if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 158 159 cmd /C exit /B %ERROR_CODE%
下面对上述批处理文件展开详细分析,首先需要把一些批处理常用命令讲解一下:
(1) @ 符号的作用是命令行回显屏蔽符,可以在其他批处理命令前加@符来控制该命令是否回显在控制台窗口
比如批处理中REM与@REM的区别:
REM是批处理中的注释命令,@REM的作用与REM相同,只不过在回显上有差别,如果echo off,@要与否是无所谓的.但是,如果echo on,在运行的时
候,不带@的行的DOS命令都会被回显,包括注释
(2) %HOMEDRIVE%和%HOMEPATH%
%homedrive%指操作系统所在的盘,如装在C盘,则为c:\
%HOMEPATH%指登录当前操作系统的用户的用户目录,如登录用户为administrator, 则一般为\Documents and Settings\administrator
(3) ~ 波浪号的作用是截取字符串
如: 假设set str=123456789
则 %str:~0,1% 表示要从字符串的第0位直到截取字符串最左边一个字符后的位置。截取结果为1
%str:~0,-1%表示要从字符串的第0位直到截取字符串最右边一个字符后的位置。截取结是为12345678
(4) %~dp0 : 获取当前批处理的运行目录路径
(5) setlocal :启动批处理文件中环境变量的本地化,和endlocal配套使用,使得某些变量的变化只是维持在setlocal和endlocal之间 ,如:
set var=123
setlocal
set var=abcd
endlocal
echo %var%
当echo时,var变量应为123
(6) %[1-9]表示参数,参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)分隔的字符串。变量可以从%0到%9,%0表示批处理命令本身,其它参
数字符串用%1到%9顺序表示。
(7) shift , 去掉第一个参数,后面的参数依次向前移