以前看过多次MAVEN IN ACTION ,最近又有所遗忘,顺便又看了一遍,简要记录下要点
<pre code_snippet_id="616475" snippet_file_name="blog_20150310_1_241735" name="code" class="html" style="line-height: 28px;">Maven 的POM.XML基本结构如下所示
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.toyewai</groupId>
<modelVersion>4.0.0</modelVersion>
<artifactId>ebossweb</artifactId>
<packaging>war</packaging>
<name>ebossweb</name>
<description>eboss-web</description>
<version>1.0</version>
</project>
modelVersion定义类pom模型版本,maven3只能是4.0.0,
groupId定义项目属于哪个组,如googleCode简历在一个myapp项目上,哪groupId应该为com.googlecode.myapp,如果公司myapp有同样的项目,那groupId为com.mycom.myapp;
artifactId定义项目唯一的ID,如一般为项目分配为myapp-util,myapp-domain,myapp-web;
version 项目版本,如1.0SANPSHOT.及快照,项目还在开发中,
Name元素声明一个友好的项目名称,
MAVEN项目源代码一般放在src/main/java文件夹下 ,即默认的文件路径。Maven就会自动寻找该文件夹下的项目,一般来说类包名也是基于POM定义的groupId和artifactId定义的,譬如以上包名一般定义为com.taoyewai.ebossweb,这样逻辑也相对清晰。
编译命令:mvn clean compile;输出目录target/,代码编译至/target/class,clean,compile均是插件的的方式。
打包命令:mvn clean package,执行之后,maven先执行junit测试指令,然后打包到target文件夹下,生成JAR包或者war包
使用Archetype生成项目骨架
在Maven3执行:
mvn archetype:generate
这样依次会提示输入编号,然后回车,后提示输入groupId,artifactId,version以及包名package
该插件自动包路径生成,并且生成一个App类,迅速建立项目骨架,
使用m2eclipse建立项目
MAVEN坐标,通过坐标引入各种JAR包,管理各种依赖关系
基本的坐标定义如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.0.RELEASE</version>
<type>jar</type>
</dependency>
groupId,顶一个MAVEN隶属的实际项目,通常与域名法向一一对应。
artifactId,定义的是一个实际项目中一个MAVEN项目,推荐是使用实际项目名称作为artifactId前缀,例如以上的坐标,我们使用spring-beans作为artifactId
version,maven所使用的版本。
Packaging,打包方式,使用JAR打包,生成的为.Jar.
Classifier,帮助定义一些附属构件,
Type:依赖类型,默认为jar,一般不用改
Scope:依赖范围;
Optional:依赖是否可选;
exclusions:用来排除传递性依赖
MAVEN依赖范围
MAVEN依赖范围是用来控制与 编译、测试、运行三种依赖范围的关系。
编译(compile),默认的是使用该依赖范围,此范围对于编译测试运行三种都有效,如上spring-bean对于三种范围都是用该依赖;
Test:测试依赖,只对于测试有效,运行和编译阶段都无效,典型的是JUnit,
Provided:以提供的依赖范围,对于编译和测试有效,对于运行项目中无效,典型的例子是servlet-api,由于该容器已提供,就不需要MAVEN重复引用。
Runtime:运行依赖范围,对于测试盒运行都有效,但编译主代码无效,如JDBC驱动的实现,编译只需提供JDBC接口即可,其他使用时候才需要实现上述接口的JDBC驱动。
System,系统依赖,与provided依赖范围一致,但改依赖范围必须通过systemPath元素制定依赖文件的路径。
Import:导入依赖范围,该依赖范围不会对三种产生实际影响、
传递性依赖
譬如项目account-mail,有一个依赖spring-core,此包又依赖于commons-logging,那么commons-logging就会成为account-mail的compile范围依赖,此就是一个传递性依赖。
排除依赖
但这种依赖传递会存在隐患,可能会导致同一个库的不同版本被导入多次,此时可以用exclusions解决:
<dependency>
<groupId>opensymphony</groupId>
<artifactId>webwork</artifactId>
<version>2.2.5</version>
<exclusions>
<exclusion>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
</exclusion>
</exclusions>
</dependency>
排除性依赖不需要版本号,
这样一来,项目就不会自己导入webwork中的freemarker依赖
maven还有个可选依赖的设置,在当前项目A设置对某个依赖是可选的,<optional>true</optional>
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
这样设置后,再有个项目X依赖A时,如果X中没有B中的类路径,则不会把B依赖加进来。
分类依赖
当同一个模块,所依赖的几个模块版本都相同时,可以使用maven里的属性做分类依赖,依赖版本升级时改一处即可
[html] view plaincopy
1. <properties>
2. <springframework.version>2.5.6</springframework.version>
3. </properties>
4. <dependencies>
5. <dependency>
6. <groupId>org.springframework</groupId>
7. <artifactId>spring-core</artifactId>
8. <version>${springframework.version}</version>
9. <type>jar</type>
10. <scope>compile</scope>
11. </dependency>
12. <dependency>
13. <groupId>org.springframework</groupId>
14. <artifactId>spring-beans</artifactId>
15. <version>${springframework.version}</version>
16. <type>pom</type>
17. <scope>compile</scope>
18. </dependency>
19. <dependency>
20. <groupId>org.springframework</groupId>
21. <artifactId>spring-context</artifactId>
22. <version>${springframework.version}</version>
23. <type>jar</type>
24. <scope>compile</scope>
25. </dependency>
26. <dependency>
27. <groupId>org.springframework</groupId>
28. <artifactId>spring-context-support</artifactId>
29. <version>${springframework.version}</version>
30. <type>jar</type>
31. <scope>compile</scope>
32. </dependency>
33. </dependencies>
优化依赖
可概括为三个命令
mvn dependency:list
表示依赖列表,maveneclipse插件已经实现,有图形化显示,在pom.xml的dependencies页
mvn dependency:tree
表示依赖列表,maveneclipse插件已经实现,有图形化显示,在pom.xml的dependencyhierarchy页
mvn dependency:analyze
查找出在编译和测试中未使用但显示声明的依赖
MAVEN 生命周期
Maven生命周期包含了 清理、初始化、编译、测试、打包、集成测试、验证、部署、和站点生成所有构建步骤,而实际的任务都交由插件完成。
编辑插件为maven-compiler-plugin,测试为maven-surefire-plugin等,
Clean 生命周期
1、 pre-ckean,清理前需要的工作;
2、 clean 清理上一次构建生成的文件
3、 post-clean:执行一些清理后的工作。
Default生命周期
包括真正的构建所需要的步骤,
· validate
· generate-sources
· process-sources
· generate-resources
· process-resources 复制并处理资源文件,至目标目录,准备打包。
· 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 。
· pre-integration-test
· integration-test
· post-integration-test
· verify
· install 将包安装至本地仓库,以让其它项目依赖。
· deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
MAVEN的聚合和继承
MAVEN的聚合是把各个模块聚合在一起执行,继承性是指各模块相同的依赖和插件配置等。
灵活构建
我们可以通过<properties>元素定义一个或多个MAVEN属性,然后其他地方使用${属性名称}引用,如spring版本属性
<properties>
<springframework.version>2.5.6</springframework.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
内置属性:${basedir}比表示项目根目录,即包含pom.xml文件目录,${version}项目版本;
POM属性,${project.artifactId}对应了<project><artifactId>元素的值
${project.build.sourceDirectory}:项目主源码目录,默认为src/main/java
${project.build.directory}:项目构建输出目录,默认为target/
${project.outputDirectory}:项目代码编译输出目录,默认为target/classes/
${project.groupId}:项目groupId
${project.artifactId}:项目的artifactId
等等
Setting属性,引用setting.xml文件中的XML元素的值,如常用的${settings.localRepository}指向本地仓库的地址。
JAVA系统属性。
环境变量属性.
多模块项目中可使用POM属性,如:
资源的过滤
· 利用filter实现对资源文件(resouces)过滤
mavenfilter可利用指定的xxx.properties中对应的key=value对资源文件中的${key}进行替换,最终把你的资源文件中的username=${key}替换成username=value
· 利用profile来切换环境
mavenprofile可使用操作系统信息,jdk信息,文件是否存在,属性值等作为依据,来激活相应的profile,也可在编译阶段,通过mvn命令加参数 -PprofileId 来手工激活使用对应的profile
结合filter和profile,我们就可以方便的在不同环境下使用不同的配制
二,配制:
在工程根目录下添加3个配制文件:
· config-dev.properties --开发时用
· config-test.properties --测试时用
· config-product.properties --生产时用
工程根目录下的pom文件中添加下面的设置:
<build>
<resources>
<!-- 先指定 src/main/resources下所有文件及文件夹为资源文件 -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<!-- 设置对auto-config.properties,jdbc.properties进行过虑,即这些文件中的${key}会被替换掉为真正的值 -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>auto-config.properties</include>
<include>jdbc.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>dev</id>
<!-- 默认激活开发配制,使用config-dev.properties来替换设置过虑的资源文件中的${key} -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<filters>
<filter>config-dev.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>test</id>
<build>
<filters>
<filter>config-dev.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>product</id>
<build>
<filters>
<filter>config-product.properties</filter>
</filters>
</build>
</profile>
</profiles>
三,使用:
· 开发环境:
filter是在maven的compile阶段执行过虑替换的,所以只要触发了编译动作即可,如果像以前一样正常使用发现没有替换,则手工clean一下工程(eclipse -> Project -> Clean)【这里你应该要安装上maven插件,因为替换是maven做的,不是eclipse做的,所以这里的clean应当是触发了maven的compile】,然后在Tomcat上也右键 -> Clean一下即可,然后你去tomcat目录下会发现你的工程的资源文件里面的${key}被替换为对应的config-xx的值了
如果上面还不行,那么就使用maven插件或者手工控制台下打maven编译命令吧
因为pom.xml中设置了dev为默认激活的,所以默认会把config-dev拿来进行替换${key}
· 测试环境
手工编译,打包:maven cleaninstall -Ptest --激活id="test"的profile
· 生产环境
手工编译,打包:maven cleaninstall -Pproduct --激活id="product"的profile
四、使用eclipse 创建web项目
1、开启eclipse,右键new——》other,如下图找到maven project
2、选择maven project,显示创建maven项目的窗口,勾选如图所示,Create a simple project
3、输入maven项目的基本信息,如下图所示:
4、完成maven项目的创建,生成相应的maven项目结果,如下所示,此处有部分结构是项目不需要的,我们需要去掉:
5、选择项目,右键选择Properties,进入属性页面,选择到Maven菜单下,如下图所示:
6、选择java版本为1.7,并去掉其他两项,如下图:
7、点击ok之后,再次回到项目结构,此时项目结构比较清晰,符合我们想要创建的maven项目
8、此时webapp下的结果还没有显示出来,因为此时我们还没有配置此的项目为web项目,再次进去Properties配置,如下图所示:
9、点击Further configuration available...,如下:
10、配置src/main/webapp,并勾选生成web.xml的选项,如下:
11、确定之后,返回到maven菜单下去掉Dynamic Web Module的勾选,点击ok,如下所示,webapp目录结构显示出来了:
12、此时还需要配置,src/main/webapp为“/”项目的根目录,如下所示:
13、完成如上配置后,最后完成maven webapp项目结构如下图所示: