Maven的两个核心概念:坐标和依赖。
通过一些元素进行定义,包括groupId、artifactId、version、packaging、classifier。
依赖范围主要用来控制与三种classpath(编译classpath、测试classpath、运行classpath)的关系。
compile: 编译依赖范围
test: 测试依赖范围
provided: 已提供依赖范围,例如Servlet-api,编译和测试需要,但运行时由容器提供,不需重复引入
runtime: 运行时依赖
system: 系统依赖范围;主要涉及本机系统绑定
import: 导入依赖范围
坐标和依赖是任何一个构件在Maven世界中的逻辑表示方式,构件的物理表示方式是文件,Maven通过仓库来统一管理这些文件。
-仓库布局 大致为:groupId/artifactId/version/artifactId-version.packaging
-仓库分类 对Maven来说,只分为本地参考和远程仓库。Maven查找构件次序:优先本地仓库,本地无则去远程仓库查找。私服是一种特殊的远程仓库,为节省带宽和时间,应在局域网内假设一个私服
自定义本地仓库目录位置,例如C盘空间不足等。 修改~/.m2/setting.xml,设置localRespository元素的值
<localRepository>D:/Java/apache-maven-3.0.5/local_repos</localRepository>
默认情况下,~/.m2/settings.xml文件不存在,用户需要从Maven的安装位置,复制一份%MAVEN_HOME%/conf/settings.xml拷贝再进行编辑。
当依赖范围是system时,Maven直接从本地文件系统解析构件
根据依赖坐标计算仓库路径后,优先尝试直接从本地仓库寻找构件
本地不存在,如果依赖版本是显式的发布版本构件,如1.2、1.2-beta-1等,则遍历所有远程仓库
如果依赖的版本是RELEASE或者LATEST,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或者LATEST真实值,然后基于这个真实值检查本地和远程仓库
如果依赖的版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,与本地元数据合并后得到最新快照版本的值,然后检查本地仓库,或者从远处仓库下载
如果最后解析得到的构件版本是时间戳格式的快照,如1.4.1-20091104.121450-121,则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构件。
当依赖的版本不明晰的时候,如RELEASE/LATEST/SNAPSHOT,Maven需要基于更新远程仓库的更新策略来检查更新
使用Maven进行日常开发,常见问题就是如何寻找需要的依赖,我们可能只知道需要使用类库的项目名称,但添加Maven依赖需要提供确切的Maven坐标;我们可以通过使用仓库搜索服务来根据关键字得到Maven坐标。
MVNrepository
Sonatype Nexus
echo %JAVA_HOME% java -version #查看Java版本
将压缩包解压到指定目录中,个人建议D:/java/apache-maven-3.0.5
需要设置环境变量,将Maven安装配置到操作系统环境中
设置MAVEN_HOME,指向Maven安装目录:D:/java/apache-maven-3.0.5
修改PATH变量,在末尾添加";%MAVEN_HOME%/bin 检查设置
echo %MAVEN_HOME% mvn -v #查看Maven版本
全局设置,修改%MAVEN_HOME%/conf/settings.xml
用户设置(在Linux多用户情况下),拷贝%MAVEN_HOME%/conf/settings.xml到~.m2\settings.xml,修改此文件,在用户范围内定制Maven的行为。
在用户目录下可以发现.m2文件夹。默认情况,该文件夹下放置了Maven本地仓库.m2/repository,所有Maven构件被存储在本地此目录下,以方便在多个项目间重用。
在Linux多用户环境下,用户需要复制%MAVEN_HOME%/conf/settings.xml到~.m2\settings.xml,这是一条最佳实践。
mvn help:system #打印当前Java系统属性和环境变量
编辑settings.xml,添加代理配置如下:
<proxy> <id>optional</id> <active>true</active> <protocol>http</protocol> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> </proxy>
m2eclipse插件,其中模块Maven Integrateion for WTP(Optional),可以让Eclipse自动读取POM信息,并配置WTP项目(支撑WEB应用开发)。
备注:需要配置Eclipse,调整vm配置指向本机JDK
通常需要配置MAVEN_OPTS=-Xms128m -Xmx512m,因为Java默认最大内存往往不能够不满足Maven运行的需要,否则很容易得到java.lang.OutOfMemoryError.
<!-- compiler插件, 设定JDK版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>1.5</source> <target>1.5</target> <showWarnings>true</showWarnings> </configuration> </plugin>
maven有两种生成可执行jar包的插件,能够自动加载依赖包。分别为 maven-assembly-plugin 和appassembler-maven-plugin。
appassembler-maven-plugin 的优势是能够自动生成window和linux的启动脚本
maven-assembly-plugin 生成jar包后需要执行 java -jar **.jar命令运行jar包。
根目录中放置pom.xml
src/main/java目录中,放置项目的主代码
src/main/resources目录中,放置项目的的资源文件,如配置文件.ini/.xml/*.propeties
src/test/java目录中,放置项目的测试代码
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> </exclusions> </dependency>
<properties> <!-- 主要依赖库的版本定义 --> <cxf.version>2.7.4</cxf.version> </properties> <!-- SOAP begin --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-core</artifactId> <version>${cxf.version}</version> <exclusions> <!-- use javax.mail.mail instead --> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-javamail_1.4_spec</artifactId> </exclusion> <!-- use javax.activation.activation instead --> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-activation_1.1_spec</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> <exclusions> <!-- see above --> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-javamail_1.4_spec</artifactId> </exclusion> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-activation_1.1_spec</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <!-- SOAP end -->
Maven提倡“约定优于配置”(Convention Over Configuration),这是Maven最核心的设计理念之一。原因之一是,使用约定可以大量减少配置。
对Maven 3,超级POM在文件$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。主要定义包括:
仓库及插件仓库
超级POM中关于项目结构约定的定义,包括:项目的主输出目录、主代码输出目录、最终构件的名称格式、测试代码输出目录、主源码目录、脚本源码目录、测试源码目录、主资源目录和测试资源目录。
核心插件版本设定
项目报告输出目录
项目发布的profile
mvn dependency:list #查看项目已解析依赖(Resolved Dependency) mvn dependency:tree #查看当前项目的依赖树 mvn dependency:analyze #工具帮助分析当前项目的依赖,重点关注"Used undeclared dependencies"和"Unused declared depend