首页 > 代码库 > Maven实战读书笔记(3)

Maven实战读书笔记(3)

POM是什么?

1、像MakeMakefileAntbuild.xml一样,Maven项目的核心是pom.xml

2POM (Project Object Model, 项目对象模型) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等等

 

如何编写一个Hello WorldPOM?

新建一个名为pom.xml的文件,输入内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<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">

       <modelVersion>4.0.0</modelVersion>

       <groupId>com.juvenxu.mvnbook</groupId>

       <artifactId>hello-world</artifactId>

       <version>1.0-SNAPSHOT</version>

       <name>Maven Hello World Project</name>

</project>

 

对楼上的配置进行解释

1、代码的第一行是XML头,指定了该xml文档的版本和编码方式

2、紧接着的project元素,project是所有pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素(虽然这些属性不是必须的,但使用这些属性能够让第三方工具,如IDE中的XML编辑器,帮助我们快速编辑POM)

3、根元素下的第一个子元素modelVersion指定了当前POM模型的版本,对于Maven2Maven3来说,它只能是4.0.0

4、最重要的groupIdartifactIdversion,这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jarpom或者war都是以基于这些基本的坐标进行区分的

 

groupId是什么意思?

groupId定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联,比如在googlecode上建立了一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp

 

artifactId是什么意思?

artifactId用于定义该项目下的某个模块,比如myapp-utilmyapp-domainmyapp-web

 

version是什么意思?

version指定了Hello World项目当前的版本——1.0.SNAPSHOT

 

SNAPSHOT是什么意思?

SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展,version会不断更新,如升级为1.01.1-SNAPSHOT1.12.0

 

最后的是name是什么意思?

最后的name元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个POM声明name,以方便信息交流

 

Maven中的项目主代码和测试代码分别是指?

1、项目的主代码会被打包到最终构建中(jar)

2、项目的测试代码只在运行测试时用到,不会被打包

3、默认情况下,Maven假设项目主代码位于src/main/java目录,测试代码位于src/test/java

 

关于Java代码有两点需要注意

1、应该把项目主代码放到src/main/java目录下(遵循Maven的约定),而无需额外的配置,Maven会自动搜寻该目录找到项目主代码

2、该Java类的包名是com.juvenxu.mvnbook.helloworld,这与之前在POM中定义的groupIdartifactId相吻合,一般来说,项目中Java类的包都应该基于项目的groupIdartifactId,这样更加清晰、更加符合逻辑,也方便搜索构件或者Java

 

在项目根目录下运行命令 mvn clean compile

1clean命令告诉Maven清理输出目录target,就是删除target目录

2compile命令告诉Maven编译项目主代码

3、默认情况,Maven构建的所有输出都在target/目录中,compile任务将项目主代码编译至target/classes目录,(target\classes\com\juvenxu\mvnbook\helloworld\HelloWorld.class)

4、执行任务顺序是: clean:clean任务、resources:resources任务、compile:compile任务,resources任务是处理项目资源(src/main/resourcessrc/test/resources

 

上面提到的clean:cleanresources:resourcescompile:compile是指?

格式应该是:插件:插件目标

比如clean:cleanclean插件的clean目标,以此类推

 

引入JUnit依赖

Java世界中,由Kent BeckErich Gamma建立的Junit是事实上的单元测试标准,要使用JUnit,首先需要为Hello World项目添加一个JUnit依赖,修改项目的POM如下:

<?xml version="1.0" encoding="UTF-8"?>

<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">

       <modelVersion>4.0.0</modelVersion>

       <groupId>com.juvenxu.mvnbook</groupId>

       <artifactId>hello-world</artifactId>

       <version>1.0-SNAPSHOT</version>

       <name>Maven Hello World Project</name>

       <dependencies>

              <dependency>

                     <groupId>junit</groupId>

                     <artifactId>junit</artifactId>

                     <version>4.7</version>

                     <scope>test</scope>

              </dependency>

       </dependencies>

</project>

 

对上面配置进行解释

1、配置中添加了dependencies元素,该元素下可以包含多个dependency元素

2、添加junit坐标,Maven自动下载junit-4.7.jar

3scope元素指的是依赖范围

 

依赖范围是指?

1、若依赖范围为test表示该依赖只对测试有效,换句话说,测试代码中import JUnit代码是没问题的,但是如果在主代码中用import JUnit代码,就会造成编译错误。

2、若不声明依赖范围,那么默认值就是compile,表示该依赖对主代码和测试代码都有效

 

一个典型的单元测试包含三个步骤

1、准备测试类及数据

2、执行要测试的行为

3、检查结果

另外JUnit3中,约定所有需要执行测试的方法都以test开头,JUnit4中,测试方法都以@Test 进行标注

 

执行mvn clean test
执行该命令会依次执行如下任务:

任务名

插件和版本号

Clean

Maven-clean-plugin:2.5

Resources

Maven-resources-plugin:2.6

Compile

Maven-compile-plugin:2.5.1

testResources

Maven-resources-plugin:2.6

testCompile

Maven-compile-plugin:2.5.1

Test

Maven-surefire-plugin:2.12.4

之后就是Surefire report directory: target\surefire-reports

执行测试,测试完成后会在target\surefire-reports下生成测试报告,一个.txt文件一个.xml文件,测试报告显示一共运行了多少测试,失败多少,出错了多少,跳过了多少

 

打包和运行 mvn clean package

1、默认打包类型jar,会执行jar:jar任务

2、将主代码打包成hello-world-1.0-SNAPSHOP.jar

3、也可以使用finalName来自定义该文件的名称

 

如何让其他的Maven项目直接引用自己的jar mvn clean install

1、执行安装任务install:install

2、将该项目的pomjar安装到本地仓库,便于其他maven项目引用

 

直接使用mvn clean install命令打包的jar文件无法直接执行,虽然有main方法

因为带有main方法的类信息不会添加到manifest(打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)

 

那么如何解决jar文件有main方法但是不能执行这一问题

为了生成可执行的jar文件,需要借助maven-shade-plugin,配置该插件如下:

<build>

              <plugins>

                     <plugin>

                            <groupId>org.apache.maven.plugins</groupId>

                            <artifactId>maven-shade-plugin</artifactId>

                            <version>1.2</version>

                            <executions>

                                   <execution>

                                          <phase>package</phase>

                                          <goals>

                                                 <goal>shade</goal>

                                          </goals>

                                          <configuration>

                                                 <transformers>

                                                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

                                                 <mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>

                                                        </transformer>

                                                 </transformers>

                                          </configuration>

                                   </execution>

                            </executions>

                     </plugin>

              </plugins>

       </build>

plugin元素在POM中的相对位置应该是<project> <build> <plugins>下面

配置<mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>,项目在打包时会将该信息放到MANIFEST

 

现在执行mvn clean install

target目录下会生成两个jar

hello-world-1.0-SNAPSHOT.jar,可执行的jar

orginal-hello-world-1.0-SNAPSHOT.jar,原始的jar

打开hello-world-1.0-SNAPSHOT.jarMETA-INF/MANIFEST.MF,可以看到如下这样一行信息: Main-Class: com.juvenxu.mvnbook.helloworld.HelloWorld

现在,在项目根目录下执行: java -jar original-hello-world-1.0-SNAPSHOT.jar 结果是:Hello Maven


Maven实战读书笔记(3)