1. maven 安装
配置环境变量
M2_HOME : D:\My_Sduty_2015\Maven\apache-maven-3.1.1
path : %M2_HOME%\bin;
检查安装:在cmd下输入 mvn -v 可以查看maven版本,说明安装成功!
2. 初步认识 pom.xml 文件
<groupId>com.mystudy</groupId> <!-- 整个的项目 id --> <artifactId>maven_study</artifactId> <!-- 项目中某个功能模块 id (子项目) --> <version>0.0.1-SNAPSHOT</version> <!-- 版本号 : SNAPSHOT 开发中的快照版本 -->
3. 认识maven项目的目录结构
mvn_pro_01\pom.xml
mvn_pro_01\src\main\java\com\study\maven\HelloMaven.java --- 实际项目的类
mvn_pro_01\src\test\java\com\study\maven\TestHelloMaven.java --- 测试的类
mvn_pro_01\target\classes\com\study\maven\HelloMaven.class
mvn_pro_01\src\main\resources\ --- 存放资源文件,如 log4j,spring,hibernate 等的配置文件
mvn_pro_01\src\main\webapp\ --- 存放页面jsp和静态文件
mvn_pro_01\src\test\resources\ --- 存放测试的资源文件
4. 初次 mvn compile 编译时,会从网络中下载maven需要的文件和jar包
编译完成后 BUILD SUCCESS ,在项目的目录下,会产生一个和src同级的 target 目录,里面是 classes目录,编译好的目录和class就存放于此
注意:在cmd环境下运行maven命令,如编译,打包,install等等,都是cd到具体的工程名目录下再运行命令的。例如cd到 D:\maven_study\maven_pros\myMavenProject01 目录下,在运行 mvn compile 命令编译 myMavenProject01 这个工程
5. 在 mvn_pro_01\src\test\java\ 目录下,写测试类,代码中引入 junit 和 Assert 的jar包
mvn test 编译和运行测试类
6. 清除maven编译后的文件 mvn clean 这个命令会清除已经编译好的 target 文件夹
7. 给项目打包 mvn package 这个命令会给项目首先编译,测试,然后在打包(jar,war 等)
打包后的文件存放在 target 目录下
8. install项目:把项目安装到仓库(打包并install到本地maven仓库)命令 mvn install
9. maven仓库:默认的位置是在“我的文档”中,“我的文档”目录下的 \.m2\repository 目录中
10. maven全球中央仓库URL: http://mvnrepository.com/
************************************************************
11. 自定义“本地仓库”的位置:
(1)建立目录 D:\My_Sduty_2015\Maven\m2_repos\repository .( 建立 m2_repos 目录和 repository 子目录)
(2)将maven安装目录 D:\My_Sduty_2015\Maven\apache-maven-3.1.1\conf 中的 settings.xml 文件打开,复制注释中的 <localRepository> 元素,修改为 <localRepository>D:\My_Sduty_2015\Maven\m2_repos\repository</localRepository>
(3)将 settings.xml 文件拷贝到 D:\My_Sduty_2015\Maven\m2_repos 目录下,和 repository 目录同级,这时候再编译,maven会重新下载相关文件到新的仓库中
(4)如果要将旧的仓库移植到新的仓库,只需要把旧仓库repository目录下的内容拷贝到新的repository目录下即可
12. 在maven中央仓库中找到需要引入的jar文件的<groupId>,<artifactId>,<version>坐标
(1)在maven的安装目录下 D:\My_Sduty_2015\Maven\apache-maven-3.1.1\的 lib 目录中找到 maven-model-builder.jar 这个jar包,解压并找到里面的 pom-xxx.xml 文件,打开并找到仓库定义标签<repositories>,里面的 <url>http://repo.maven.apache.org/maven2</url> 就是maven中央仓库的地址
(2)在浏览器中打开这个URL的地址 http://repo.maven.apache.org/maven2 ,进入到 The Central Repository 页面中,在搜索框中搜索,即可找到相应的jar包,并查看其<groupId>,<artifactId>,<version>坐标。
13. 构建maven骨架结构:因为maven项目的目录结构是固定的 src\main\java,src\test\java,所以可以直接用命令来构建maven项目结构(不需要手动创建结构)
(1)构建命令 mvn archetype:generate ,第一次时,它会下载和这个命令相关的jar文件等
注意:在运行“构建命令” mvn archetype:generate 之前,要cd 到想要创建项目的父目录一级 parent_directory(就是在parent_directory目录下构建工程 maven_project03 )
(2)和命令项目文件下好后,它会提示你安装的maven.archetype的版本,默认选择6(最新版)
(3)安装完成后,它会提示你定义 groupId,artifactId,version 的项目坐标元素
<groupId>com.mystudy</groupId> <artifactId>maven_project03</artifactId> <version>0.0.1-SNAPSHOT</version>
(4)按步骤定义完成后,项目 maven_project03 就自动生成了,可以查看里面的结构,有生成好的pom.xml,包目录和java文件等等。
(5)简洁创建:创建项目同时定义参数,可以用 mvn archetype:generate -DgroupId=com.mystudy -DartifactId=maven_project03 -Dversion=0.0.1-SNAPSHOT 命令来创建项目,这样就不需要后续的Dos提示的步骤输入 groupId,artifactId,version 等坐标元素了
14. 在eclipse中设置maven(设置自己maven的安装目录和 settings.xml 配置)
(1)在 window / preferences / maven 菜单中,设置 Installations 和 User Settings
(2)其中 Installations 就是设置我们的maven安装目录 D:\My_Sduty_2015\Maven\apache-maven-3.1.1 (即环境变量中 M2_HOME 的值)
(3)User Settings 就是设置我们本地仓库中 settings.xml 的文件所在目录 D:\My_Sduty_2015\Maven\m2_repos\settings.xml 就可以了
15. 在eclipse中创建 maven 项目时,要选择项目的 archetypes 属性,我们通常会选择 maven-archetype-quickstart 或者 maven-archetype-webapp (web项目)这两个。
************************************************************
16. 在eclipse中运行maven命令:在maven项目的 pom.xml 文件上点击右键 Run as --> Maven build ... (第二个选项)--> 在Goals的输入框中输入命令,例如 clean test ,表示先清空原来的,然后在运行test测试。
运行已输入过的命令: pom.xml 文件上点击右键 Run as --> Maven build (第一个选项)
查看错误的报告:在 target 里面的 surefire-reports 目录下 TEST-xxx 文件,双击查看。
17. 在eclipse中打包: pom.xml 文件上点击右键 Run as --> Maven build ... --> 在Goals的输入框中输入命令,例如clean package ,先clean再打包
18. 在eclipse中,把项目发布到本地仓库: pom.xml 文件上点击右键 Run as --> Maven build ... --> 在Goals的输入框中输入命令,例如 clean install ,先clean再install
注意:在Eclipse中,运行maven命令,通常前面加上clean命令,这样是在执行后续命令前,先将工程clean 清理一下(会清除掉 target 文件夹)。
19. 依赖传递:如果我们在“A”工程中,通过<dependency>引入(依赖)了“B”工程,那么“B”工程 pom.xml 中通过<dependency>引入的所有jar文件,会同时被引入到A工程的名为 Maven Depandencies 的 library中,可以在此目录下找到“B”工程的所有依赖的jar包,这个就是“依赖传递”。
注意:
(1)“依赖传递”只能是作用域为 compile 的jar包才有效 <scope>compile</scope>
(2)“间接依赖”(依赖级别相同时):如果 A 项目依赖 this-1.0.jar,B 项目依赖 this-2.0.jar,而 C 项目又要依赖 A 和 B 两个项目,那个 C 会依赖那个 版本的 this.jar 呢?这时在C项目的pom.xml中<dependency>中,A和B项目哪个写在前面,则依赖哪一个项目下的this.jar,比如依赖中 A 项目写在前面,则依赖 this-1.0.jar 这个版本的jar包。
(3)“间接依赖”(依赖级别不同时):比如 A 依赖 dbunit.jar,而 dbunit.jar 又依赖于 commons-logging1.0.jar,而 B 项目直接依赖 commons-logging2.0.jar,那么如果 C 依赖 A 和 B 项目,则 C 会间接依赖 B 项目下的 commons-logging2.0.jar 这个文件,因为它的依赖级别更高。在几个jar包都是间接依赖的时候,会取依赖级别较高的jar,也就是取依赖传递的次数最少的那个jar包。
注意:“依赖级别相同时,取位置靠前的;依赖级别不同时,取级别高(路径短)的”
(4)“排除依赖”:排除某个依赖工程中的jar包依赖,如 C 依赖 A 项目,又不想用 A 中的 commons-logging.jar 依赖
<dependency> <groupId>${project.groupId}</groupId> <artifactId>A</artifactId> <version>${project.version}</version> <exclusions> <!-- 排除依赖 --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
20. maven 隐藏变量:
${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为target
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件的任意节点的内容
例如:在每个pom.xml中,肯定都有 groupId,version等节点(注意:是根节点下面的,不是dependency标签里面的),所以可以有如下的写法 ${project.groupId}
<dependency> <groupId>${project.groupId}</groupId> <artifactId>maven_project04</artifactId> <version>${project.version}</version> <scope>test</scope> </dependency>
************************************************************
21. scope “作用范围” 属性:<dependency>中有 <scope> 属性
其值主要为 compile,provided,
(1)compile:表示编译时就引入这个jar文件(加入依赖),这样在测试,运行,打包的时候,都会引入这个jar包,这个也是默认的值
(2)provided:表示只是在编译和测试的时候,会引入这个依赖(引入这个jar文件),在打包的时候就不会再引入这个依赖了。比如servlet-api.jar这个文件,在tomcat里面默认就有,在开发项目时需要引入,但是在打包发布到tomcat时,就不需要了
(3)test:是指在测试时会引入这个jar包,在编译和打包的时候都不会再加入这个依赖了。比如junit的jar包,只是在测试时会用到,就可以用 <scope>test</scope>,注意:作用域为test的依赖jar包,只会对 src\test 目录中的java文件起作用,对 src\main 目录中的java文件不起作用!
(4)runtime:在编译的时候不引入这个依赖,在运行的时候才加入这个依赖。比如我们在用hibernate开发时,jdbc连接的jar包,其实在编译的时候可以不引入的,只是在运行和打包的时候才需要被引入。
例如:
<dependency> <groupId>com.sun</groupId> <artifactId>tools</artifactId> <version>1.6</version> <scope>compile</scope> <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath> </dependency>
22. 在Eclipse中改动后,maven项目总是报错:
(1)将这个项目刷新 reflush
(2)将工作空间 workspace的 resolution 先关闭再打开:
在工程上点右键 --> maven --> Disable Workspace Resolution(关闭)-->然后 Enable Workspace Resolution(再打开)
(3)更新依赖:在工程上点右键 --> maven --> Update Dependencies
(3)把“maven工程”变成“普通工程”,再变成“maven工程”:(最极端的做法)
有的时候编译测试都能通过,但是在workspace中还是有错误,这个可能是工作空间的问题,解决办法为,在工程上点右键 --> maven --> Disable Dependency Management 选项(取消maven工程,变成普通工程);在工程上点右键 --> maven --> Enable Dependency Management 选项(重新变成Maven工程)。
注意:在有些版本中没有 Disable Dependency Management 选项,则先设置 右键maven --> Disable Maven Nature,然后再右键 Configure --> Convert to Maven Project (转换成Maven项目),这时它会重新编译,就不会报错了。
************************************************************
23. maven项目的聚合:
(1)比如在 Work 目录下有 A,B,C 三个工程(这三个工程属于同一个项目下的不同模块),这时可以在Work目录下(也就是 A,B,C同级的目录下)建立一个 pom.xml 文件来聚合这三个工程,这样就可以对三个工程统一测试,编译,打包
(2)在Eclipse中,聚合 A,B,C 三个工程:右键新建一个 maven 项目 general_pro ,勾选“Create a simple project (skip archetype selection)”,然后填写 groupId,artifactId,version,在 Packaging 选项中选择 pom (属于管理类型),然后生成。在这个聚合的项目中,修改 pom.xml,添加 <modules> 模块标签
<!-- 导入了下面的模块,把它们聚合在一起 -->
<modules> <module>../A</module> <!-- general_pro 的上级目录下的A目录(和聚合项目同级的A项目)--> <module>../B</module <module>../C</module> </modules>
添加完<modules>后,在聚合项目 general_pro 的 pom.xml 上 run as Maven build .. 输入 clean package 打包命令后,A,B,C 三个项目会被同时打包,可以在它们各自项目下的target目录中找到对应的打包文件。
24. maven项目的继承:
在某个项目的子模块的pom.xml中有很多属性都是相同的,比如 <groupId>,<version>,<properties> 等,所以可以把这些公共的属性提取到父类工程中,然后各个子模块工程继承它就好了。
(1)右键新建一个 maven 项目 parent_pro ,勾选“Create a simple project (skip archetype selection)”,然后填写 groupId,artifactId,version,在 Packaging 选项中选择 pom (属于管理类型),然后生成。
(2)把一些子类工程的公共属性拷贝到父类工程 parent_pro 中
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
(3)子类工程继承父类工程,在A,B,C 工程的pom.xml中,添加如下的<parent>标签
<parent> <groupId>com.mystudy</groupId> <artifactId>mavenStudy_parent</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../mavenStudy_parent/pom.xml</relativePath> </parent>
然后在各自的pom.xml中,可以去掉父类中已有的重复的属性,比如可以去掉<groupId>,<version>,<url>,<properties>等属性。
(4)可以在父类的工程中,添加<dependencyManagement>属性,依赖管理:在这里配置的依赖,不会被子项目继承,但是可以在这里定义每个依赖的版本号和作用域,这样在子项目里面就可以不用再写版本号和作用域了
<dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.google.code</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org.jasypt</groupId> <artifactId>jasypt</artifactId> <version>1.9.0</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>mavenStudyProject01</artifactId> <version>${project.version}</version> <exclusions> <!-- 排除依赖 --> <exclusion> <groupId>junit</groupId> <artifactId>junit</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement>
(5)在子类工程中pom.xml文件的<dependencies>属性中的依赖,如果在父类的<dependencyManagement>中有定义,则可以去掉子类中的版本号<version>和作用域<scope>,它们会自动继承父类的版本和作用域。
<dependencies> <!-- 去掉了版本号version和作用域scope --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> </dependency> <dependency> <groupId>com.google.code</groupId> <artifactId>kaptcha</artifactId> </dependency> <dependency> <groupId>org.jasypt</groupId> <artifactId>jasypt</artifactId> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>mavenStudyProject01</artifactId> </dependency> </dependencies>
注意:在父类工程中的某个<dependency>依赖如果定义了“排除依赖”<exclusions>,则子类工程在引入这个<dependency>依赖时,可以不用再写它的“排除依赖”了
(6)聚合和继承可以写到一个父类工程里面:(同时作为聚合以及父类的工程)
把<modules>关联的聚合项目的内容拷贝到父类工程的pom.xml里面即可(把<modules>这个标签复制过去即可)
(7)父类pom.xml和子类工程在同目录:可以把父类工程的pom.xml文件放到和子类工程目录同级的目录中,这是要注意修改引用的目录,例如:
子类引用父类的 relativePath 属性
<parent> <groupId>com.mystudy</groupId> <artifactId>mavenStudy_parent</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
以及父类中,聚合模块的引用 module 属性
<modules> <module>A</module> <!-- A,B,C 项目和父类的pom.xml在同级目录--> <module>B</module <module>C</module> </modules>