zoukankan      html  css  js  c++  java
  • maven权威指南读书笔记

    mvn clean install -X


    maven默认目录

    maven,在没有自定义的情况下,源码假定在${basedir}/src/main/java;资源文件假定在${basedir}/src/main/resources;测试代码假定在${basedir}/src/test;测试资源文件假定在${basedir}/src/test/resources;编译好的字节码在${basedir}/target/classes;可以分发的jar包在${basedir}/target。
    其中${basedir}/src/main/java和${basedir}/src/main/resources里的文件,打包后都在classpath目录下。

    资源目录并非一定要放在src/main/resources下,假设有个项目包含数百个xml文档和数百个图片,可以创建两个目录src/main/xml和src/main/images,并且配置如下:
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/xml</directory>
            </resource>
            <resource>
                <directory>src/main/images</directory>
            </resource>
        </resources>
    </build>

    超级pom里资源目录就是这样配置的。


    超级pom是maven安装的一部分。settings.xml和pom.xml文件的配置可以覆盖超级pom的设置。


    maven插件、目标

    第一次使用全新的maven运行 mvn install命令的时候,它会从中央仓库下载大部分核心插件,然后存储在maven仓库里。

    mvn help:describe -Dplugin=help
    help是一个插件,describe是此插件的一个目标,使用-Dplugin指定想要查看的插件

    mvn archetype:generate -DgroupId=com.sto -DartifactId=simple
    接下来一路回车,就会生成一个maven项目
    archetype,[ˈɑːkitaɪp],典型。archetype是“一个原始的模型或者类型”,maven有许多可用的archetype,从生成一个简单的Swing应用,到一个复杂的Web应用。
    artifact [ˈɑːtɪfækt] 手工制品,这里是构件、项目的意思。
    上面的命令默认使用maven-archetype-quickstart
     
    mvn install
    在包含pom.xml的目录下运行,打包应用

    运行程序
    java -cp target/simple-1.0-SNAPSHOT.jar com.sto.App

    maven运行时,会根据pom.xml的设置来运行,pom.xml是有多个层级的,maven需要组合多个层级的pom文件。查看组合后的pom.xml文件:
    mvn help:effective-pom
    effective [ɪˈfektɪv] 有效的;实际的

    maven插件是单个或多个maven目标的集合。maven插件有archetype、jar、compiler、surefire。
    maven目标是一个明确的任务。compiler插件有compile目标,surefire插件有test目标。
    目标可以通过配置属性来定义其行为,比如:mvn archetype:generate -DgroupId=com.sto -DartifactId=simple,配置了组Id和项目Id。


    插件前缀

     mvn org.apche.maven.plugins:maven-jar-plugin:2.2:jar
     mvn jar:jar


    生命周期和生命周期阶段

    mvn package,package是一个生命周期阶段

    maven有三个标准的生命周期,clean、default、site。
    clean包含三个生命周期阶段,pre-clean、clean、post-clean。
    default其中包含test、package、install、deploy这些阶段。deploy,复制包到远程maven仓库。

    生命周期包含一系列有序的阶段,每个阶段可以绑定零个或多个目标,比如package生命周期阶段绑定了jar:jar插件目标;clean生命周期阶段绑定了clean插件的clean目标;site生命周期包含有site生命周期阶段,该阶段绑定了site插件的site目标

    maven执行一个阶段时,会有序地执行前面的所有阶段,直到指定的那个阶段为止。
    mvn package,相当于 mvn resources:resources compiler:compile resources:testResources compiler:testCompile surefire:test jar:jar

    packaging有jar、war、maven-plugin。packaging是jar和war不同类型的构件,绑定在package生命周期阶段的插件目标也不同,有jar:jar,有war:war。


    ${}的使用
    maven有三个隐式的变量,env、project、settings。
    ${env.PATH}
    ${settings.offline}
    ${project.groupId}


    还可以在pom.xml或settings.xml中提供properties元素设置自己的属性。
    <properties>
        <foo>bar</foo>
    </properties>
    ${project.foo}或${foo}

    还可以访问java系统属性,所有可以通过java.lang.System的getProperties()方法访问的属性,${user.name}


    maven资源过滤

    resources:resources目标首先过滤资源,然后将资源复制到输出目录。
    就像在pom文件中使用${}引用变量一样,也可以在资源文件中使用。
    资源过滤即替换资源文件中的一些符号,与profile联系起来,就可以生成针对不同部署平台的构件;。
    maven默认会跳过资源过滤,我们需要显示地配置资源过滤:

    <build>
        <filters>
            <filter>src/main/my.properties</filter>
        </filters>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

    1、建立一个maven项目
    mvn archetype:generate -DgroupId=com.sto -DartifactId=simple
    2、打开resources目录,随便自定义一个文件,取名service.xml,文件内容如下:
    <service>
        <!-- ${project.version} -->
        <!-- ${env.PATH} -->
        <url>${jdbc.url}</url>
        <user>${jdbc.username}</user>
        <password>${jdbc.password}</password>
    </service>
    3、再建立一个my.properties文件,内容如下:
    jdbc.url=jdbc:hsqldb:mem:mydb
    jdbc.username=sa
    jdbc.password=123
    4、配置资源过滤
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <filters>
            <filter>src/main/my.properties</filter>
        </filters>
    </build>
    5、执行mvn package
    6、查看target/classes/service.xml
    一个示例
    7、复制service.xml并粘贴,改名为service2.xml
    8、只对某个资源过滤并复制输出到指定目录
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>service2.xml</include>
                </includes>
                <!-- 定义资源输出目录,可以不配置,默认输出到classPath -->
                <targetPath>${basedir}</targetPath>
                <filtering>true</filtering>
            </resource>
        </resources>
        <filters>
            <filter>src/main/my.properties</filter>
        </filters>
    </build>
    另一个示例

    profile

    profile是用来做什么的?它可以为特殊环境自定义特殊的构建。Maven能让你定义任意数量的profile,这些定义可以覆盖pom.xml中的任何配置。
    你可以在开发profile中,访问本地数据库,在产品profile中,访问产品数据库。
    profile也可以通过环境和平台被激活,你可以自定义一个profile,它根据不同的操作系统或不同的JDK版本有不同的行为。
    profile激活元素可以包含一个或多个选择器:包含JDK版本,操作系统参数,文件,及maven属性。
    maven3不再支持base目录下的profiles.xml文件。
    可以在settings.xml中添加profiles元素。

    <project>
        <profiles>
            <profile>
                <id>dev</id>
                <activation>
                    <activeByDefault>false</activeByDefault>
                    <jdk>1.5</jdk>
                    <os>
                        <name>Windows XP</name>
                        <family>Windows</family>
                        <arch>x86</arch>
                        <version>5.1.2600</version>
                    </os>
                    <property>
                        <!-- maven属性 -->
                        <name>mavenVersion</name>
                        <value>2.0.5</value>
                    </property>
                    <file>
                        <!-- 在基础目录中存在及不存在file2和file1才可激活 -->
                        <exists>file2.properties</exists>
                        <missing>file1.properties</missing>
                    </file>
                </activation>
            </profile>
        </profiles>
    </project>    
    View Code

    示例:为生产环境和开发环境配置不同的profile

    1、新建项目。mvn archetype:generate -DgroupId=com.sto -DartifactId=simple

    2、添加资源文件。打开resources目录,新建自定义文件service.xml,文件内容:

    <service>
        <env>${my.os}</env>
    </service>

    3、在main文件夹下新建文件夹config,添加文件 dev.properties,文件内容:my.os=win10。添加文件 pro.properties,文件内容 my.os=centos。

    4、打开pom.xml,在build元素内添加:

        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

    在project元素内添加:

    <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <os>
                    <name>Windows 10</name>
                </os>
            </activation>
            <build>
                <filters>
                    <filter>src/main/config/dev.properties</filter>
                </filters>
            </build>
        </profile>
        <profile>
            <id>pro</id>
            <build>
                <filters>
                    <filter>src/main/config/pro.properties</filter>
                </filters>
            </build>
        </profile>
      </profiles>
    View Code

     5、执行mvn package,查看target里的service.xml文件;执行mvn package -Ppro,查看target里的文件service.xml


    插件配置、目标配置、compiler插件配置

    compile阶段绑定compiler插件的compile目标,compile目标会调用javac。
    compiler插件假设所有的java源码遵循java 1.3,运行在java 1.1 JVM。
    更改配置:
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    或者:
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                            <configuration>
                                <source>1.5</source>
                                <target>1.5</target>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    建议使用第一种配置方式,第一种方式配置的是compiler插件,第二种方式配置的是compile目标。
    我们为整个插件配置source和target,是因为compiler:compile并不是我们唯一感兴趣的目标,另外还有compiler:testCompile目标。
    View Code

    maven坐标可以唯一标识一个项目,或一个插件。maven的坐标有组id,项目id,版本号,classifier。classifier,发布同样的代码,但需要生成两个独立的包,就可以使用分类器,一个使用java1.4编译,一个使用java1.6编译。分类器常用于打包构件的源码、javaDoc或者二进制集合。


    maven依赖的传递性,A项目依赖B项目,B项目又依赖C项目,我们在A项目的pom.xml文件里只需要添加对B项目的依赖即可。因为B项目也是一个maven项目,B项目的pom文件里已经定义了对C项目的依赖。


    依赖范围控制依赖在哪些classpath中可用。
    compile,默认范围,编译、测试、运行都依赖,所有的classpath中有。
    test,只在测试编译和测试运行时在classpath中有效的依赖。
    provided,servlet依赖已经由运行容器提供,不会被包含到war包中。
    runtime,在运行和测试系统时需要。


    mvn site
    会生成htlm文件,可以查看依赖,查看项目信息,查看maven插件


    mvn dependency:tree
    查看依赖树


    执行package生命周期阶段,如果surefire:test执行失败,默认会停止构建项目。
    忽略测试失败配置
    1、pom文件配置
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
        </plugins>
    </build>
    2、命令行配置
    mvn test -Dmaven.test.failure.ignore=true


    跳过单元测试
    1、pom文件配置
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

    2、命令行配置
    mvn install -Dmaven.test.skip=true


    mvn Assembly插件用来创建应用程序的压缩包

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    mvn install assembly:assembly
    示例一

    示例二,将项目源码以压缩包的形式复制一份给别人
    1、mvn archetype:generate -DgroupId=com.sto -DartifactId=simple
    2、mvn assembly:single -DdescriptorId=project

    示例三,创建一个可运行的jar文件

    1、mvn archetype:generate -DgroupId=com.sto -DartifactId=simple
    2、修改pom.xml
    添加依赖,用以观察依赖被一起打包
     <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>commons-lang</groupId>
          <artifactId>commons-lang</artifactId>
          <version>2.4</version>
        </dependency>    
      </dependencies>
     配置assembly
     <build>
        <plugins>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-2</version>
            <executions>
              <execution>
                <id>create-executable-jar</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
                <configuration>
                  <descriptorRefs>
                    <descriptorRef>
                      jar-with-dependencies
                    </descriptorRef>
                  </descriptorRefs>
                  <archive>
                    <manifest>
                      <mainClass>com.sto.App</mainClass>
                    </manifest>
                  </archive>
               </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
     3、mvn package
     4、java -jar simple-1.0-SNAPSHOT-jar-with-dependencies.jar
     5、观察
     此jar包比标准生成的jar包大很多,因为此jar包内部还真实地包含了依赖;标准jar包只是通过pom文件声明了需要哪些依赖。
     此jar包的MANIFEST.MF文件中包含有主类位置——Main-Class: com.sto.App
    View Code

    示例四,通过套件依赖组装套件

     1、mvn archetype:generate -DgroupId=com.sto -DartifactId=simple;并删除src目录,只保留pom文件
     2、修改pom文件
     类型改为pom
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>2.2-beta-2</version>
              <executions>
                <execution>
                  <id>create-project-bundle</id>
                  <phase>package</phase>
                  <goals>
                    <goal>single</goal>
                  </goals>
                  <configuration>
                    <descriptorRefs>
                      <descriptorRef>project</descriptorRef>
                    </descriptorRefs>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
      3、新建两个子项目first、second
      mvn archetype:generate -DgroupId=com.sto -DartifactId=first
      mvn archetype:generate -DgroupId=com.sto -DartifactId=second
      4、修改first、second项目的pom文件
     <build>
      <plugins>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
        </plugin>
      </plugins>
    </build>
     5、执行mvn install
     观察:maven把first、second两个项目的标准jar文件、pom文件、及项目压缩文件都复制到了maven仓库。
     6、创建一个新项目bundle,和simple并列关系或者说没有关系的项目
     mvn archetype:generate -DgroupId=com.bundle -DartifactId=bundle
     7、修改bundle的pom文件
     <packaging>pom</packaging>
     <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.sto</groupId>
          <artifactId>first</artifactId>
          <version>1.0-SNAPSHOT</version>
          <classifier>project</classifier>
          <type>zip</type>
        </dependency>
        <dependency>
          <groupId>com.sto</groupId>
          <artifactId>second</artifactId>
          <version>1.0-SNAPSHOT</version>
          <classifier>project</classifier>
          <type>zip</type>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-2</version>
            <executions>
              <execution>
                <id>bundle-project-sources</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
                <configuration>
                  <descriptorRefs>
                    <descriptorRef>
                      jar-with-dependencies
                    </descriptorRef>
                  </descriptorRefs>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>  
      8、mvn package
    View Code

    mvn archetype:generate -DgroupId=com.sto -DartifactId=simple-webapp -DarchetypeArtifactId=maven-archetype-webapp

    maven jetty插件配置
    <build>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    在命令行运行 mvn jetty:run
    最后提示[INFO] Started Jetty Server就成功运行了
    浏览器访问:localhost:8080/simple-webapp


    优化依赖
    dependencyManagement放在父pom,并声明依赖版本,这时不会把依赖添加进来。接着,在子模块里声明依赖时,不需要添加版本,会采用父pom里dependencyManagement内声明的版本。
    <project>
    <dependencyManagement>
        <dependency>
        </dependency>
    </dependencyManagement>
    </project>


    优化插件
    pluginManagement元素定义在父项目,子项目会继承。

    maven-resources-plugin插件在父pom的pluginManagement元素里配置后,子项目不需要再次声明组织ID及项目ID。

    maven-assembly-plugin插件在父pom的pluginManagement元素下配置后,还必需在子项目声明artifactId。

    新建父项目a
    1、mvn archetype:generate -DgroupId=a -DartifactId=a
    2、删除src目录,修改pom文件packaging为pom。并修改为:
     <build>
        <pluginManagement>
          <plugins>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <resources>
                        <resource>
                            <directory>src/main/config</directory>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    新建父项目b
    3、mvn archetype:generate -DgroupId=b -DartifactId=b
    4、新建src/main/resources/resource.txt,新建src/main/config/config.txt
    5、b项目pom:
     <parent>
        <artifactId>a</artifactId>
        <groupId>a</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
      <artifactId>b</artifactId>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    6、执行mvn clean package,查看target/classes文件夹


    排除传递性依赖
    <dependency>
        <groupId>xxx</groupId>
        <artifactId>a</artifactId>
        <version>1.0</version>
        <exclusions>
            <exclusion>
                <groupId>xxx</groupId>
                <artifactId>b</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    此项目依赖于a项目,a项目又依赖于b项目,这里排除了对b项目的依赖。


    可选依赖
    依赖范围和依赖传递的关系


    maven版本管理
    SNAPSHOT,开发版本,maven在安装或发布这个构件时会将该符号展开为一个日期和时间值,转换为UTC。
    LATEST指仓库中构件的最新发布版或快照版,即最近部署的那个版本。
    从maven 2.0.9开始,超级pom中锁住了一组核心插件的版本,提高了maven构建的稳定性。但非核心插件或者说没有在超级pom中指定版本的插件maven仍然会自动去仓库下载LATEST版本。不过,因为在超级pom中插件管理部分配置了不下载快照版本,插件更新策略也被设置为永不更新。所以实际上不会自动更新插件的。


    聚集和继承。聚集用来模块构建;继承父文件内容。
    maven执行带有子模块的项目时,首先载入父POM,然后定位所有子POM,然后把这些POM放入reactor(反应堆),reactor负责分析模块间的依赖关系,从而确保各模块能以适当的顺序被编译和安装。
    POM最佳实践
    如果你有一组逻辑上归类在一起的依赖,可以创建一个打包方式为pom的项目来将这些依赖集中在一起。比如,假设应用程序使用hibernate,所有使用hiberna的项目同时依赖Spring和MySql Jdbc驱动。这时,创建一个打包方式为pom的项目A,为其添加hibernate、spring、Mysql Jdbc的依赖。
    之后,哪个项目需要这一组依赖,直接依赖项目A。
    如果把A项目设置为父项目,不灵活,因为一个maven项目只能有一个父项目。

  • 相关阅读:
    二项式反演
    快速沃尔什变换
    springMVC的form标签
    springMVC的拦截器配置
    RESTful使用方法
    springMVC数据绑定
    使用spring框架自带的字符拦截器
    将idea中的项目上传至github
    springMVC的使用方式
    springMVC的概述
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/12482257.html
Copyright © 2011-2022 走看看