zoukankan      html  css  js  c++  java
  • 深入理解maven及应用

    在项目里用了快一年的maven了,最近突然发现maven项目在eclipse中build时非常慢,因为经常用clean install命令来build项目,也没有管那么多,但最近实在受不了乌龟一样的build速度,于是下定决心再看看《maven实战》吧,对于我来说,maven最主要的作用有两个方面,一个是对jar包的依赖解决功能,自己管理jar包,另一个功能就是项目的构建,打包部署。现在我觉得最重要的还是maven的生命周期和插件机制,下面就来总结一下吧。
    参考url:http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

    三套生命周期

    对于maven的生命周期来说,共有三个相互独立的生命周期,分别是clean、default、site。clean生命周期目的是清理项目,default生命周期目的是构建项目,而site生命周期目的是建立项目站点。
    每个生命周期分别包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。如clean生命周期包含pre-clean、clean和post-clean三个阶段,如果执行clean阶段,则会先执行pre-clean阶段。
    较之于生命周期阶段有前后依赖关系,三套生命周期本身是相互独立的,用户可以仅调用clean生命周期的某个阶段,也可以不执行clean周期,而直接执行default生命周期的某几个阶段。

    clean生命周期

    clean生命周期包含三个阶段,主要负责清理项目,如下:

    name des
    pre-clean executes processes needed prior to the actual project cleaning
    clean remove all files generated by the previous build
    post-clean executes processes needed to finalize the project cleaning

    default生命周期

    default生命周期定义了真正构建时所需要执行的所有步骤,包含的阶段如下:

    name des
    validate validate the project is correct and all necessary information is available.
    initialize initialize build state, e.g. set properties or create directories.
    generate-sources generate any source code for inclusion in compilation.
    process-sources process the source code, for example to filter any values.
    generate-resources generate resources for inclusion in the package.
    process-resources copy and process the resources into the destination directory, ready for packaging.
    compile compile the source code of the project.
    process-classes post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
    generate-test-sources generate any test source code for inclusion in compilation.
    process-test-sources process the test source code, for example to filter any values.
    test-compile compile the test source code into the test destination directory
    test run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
    verify run any checks to verify the package is valid and meets quality criteria.
    install install the package into the local repository, for use as a dependency in other projects locally.
    deploy done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

    site生命周期

    siet生命周期的目的是建立和发布项目站点,maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息,包含的阶段如下:

    name des
    pre-site executes processes needed prior to the actual project site generation
    site generates the project's site documentation
    post-site executes processes needed to finalize the site generation, and to prepare for site deployment
    site-deploy deploys the generated site documentation to the specified web server

    命令行与生命周期

    从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。需要注意的是,各个生命周期是相互独立的,而一个生命周期的阶段是有前后依赖关系的。例子如下:

    $mvn clean :该命令调用clean生命周期的clean阶段。实际执行的阶段为clean生命周期的pre-clean和clean阶段。
    $mvn test:该命令调用default生命周期的test阶段。实际调用的是default生命周期的validate、initialize等,直到test的所有阶段。
    $mvn clean install:该命令调换用clean生命周期的clean阶段和default生命周期的instal阶段。
    
    

    插件目标

    maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的形式存在。
    对于插件本身,为了能够复用代码,它往往能够完成多个任务。如maven-dependency-plugin有十多个目标,每个目标对应了一个功能,如 dependency:analyze、 dependency:tree和dependency:list。这是一种通用的写法,冒号前面是插件前缀,后面是该插件的目标。

    插件绑定

    maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,已完成某个具体的构建任务。例如项目编译这一任务,它对应了default生命周期的compile阶段,而maven-compiler-plugin这一插件的compile目标能够完成该任务,因此将他们绑定。

    • 内置绑定
      maven在核心为一些主要的生命周期接到绑定了很多插件的目标,如下:
      clean和site生命周期相对简单。
    clean	clean:clean
    site	site:site
    site-deploy	site:deploy
    

    default生命周期与插件目标的绑定关系有点复杂一些。这是因为对于任何项目来说,例如jar项目和war项目,他们的项目清理和站点生成任务是一样的,不过构建过程会有区别。例如jar项目需要打成jar包,而war项目需要打成war包。
    由于项目的打包类型会影响构建的具体过程,因此,default生命周期的阶段与插件目标的绑定关系有项目打包类型所决定的,打包类型是通过pom中的packaging元素定义的。最常见的打包类型是jar,它也是默认的打包类型。基于该打包类型,default生命周期的内置绑定关系如下:

    process-resources	resources:resources
    compile	compiler:compile
    process-test-resources	resources:testResources
    test-compile	compiler:testCompile
    test	surefire:test
    package	ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
    install	install:install
    deploy	deploy:deploy
    
    • 自定义绑定
      除了内置绑定以为,用户还能够自己选择奖某个插件目标绑定到生命周期的某个阶段以执行更多更特色的任务。
    
    <!-- 自动复制资源文件件到根目录 -->  
                <plugin>  
                    <groupId>org.apache.maven.plugins</groupId>  
                    <artifactId>maven-resources-plugin</artifactId>  
                    <version>2.6</version>  
                    <configuration>  
                        <includeEmptyDirs>true</includeEmptyDirs>  
                        <encoding>GBK</encoding>  
                        <nonFilteredFileExtensions>  
                            <nonFilteredFileExtension>exe</nonFilteredFileExtension>  
                            <nonFilteredFileExtension>zip</nonFilteredFileExtension>  
                            <nonFilteredFileExtension>vbs</nonFilteredFileExtension>  
                            <nonFilteredFileExtension>sh</nonFilteredFileExtension>  
                        </nonFilteredFileExtensions>  
                    </configuration>  
                    <executions>  
                        <execution>  
                            <id>copy-resources</id>  
                            <phase>validate</phase>  
                            <goals>  
                                <goal>copy-resources</goal>  
                            </goals>  
                            <configuration>  
                                <includeEmptyDirs>true</includeEmptyDirs>  
                                <outputDirectory>${project.build.directory}</outputDirectory>  
                                <excludes>  
                                    <exclude>agentmanager.jsmooth</exclude>  
                                    <exclude>assembly.xml</exclude>  
                                </excludes>  
                                <resources>  
                                    <resource>  
                                        <directory>src/main/resources/</directory>  
                                        <filtering>true</filtering>  
                                    </resource>  
                                </resources>  
                            </configuration>  
                        </execution>  
                    </executions>  
                </plugin>  
    

    如上图定义了一个id为copy-resources的任务,绑定到default生命周期的validate阶段,绑定的插件为maven-resources-plugin,插件目标为copy-resources。即用插件的copy-resources功能来实现项目资源文件的拷贝。

    
    <!-- 自动复制maven依赖包到lib目录 -->  
                <plugin>  
                    <groupId>org.apache.maven.plugins</groupId>  
                    <artifactId>maven-dependency-plugin</artifactId>  
                    <version>2.1</version>  
                    <executions>  
                        <execution>  
                            <id>copy</id>  
                            <phase>install</phase>  
                            <goals>  
                                <goal>copy-dependencies</goal>  
                            </goals>  
                            <configuration>  
                                <outputDirectory>lib</outputDirectory>  
                            </configuration>  
                        </execution>  
                    </executions>  
                </plugin>  
    

    同上,定义了一个id为copy的任务,利用插件maven-dependency-plugin的copy-dependencies目标绑定到default生命周期的install阶段,来实现项目依赖的jar包的自动复制。

    当插件目标被绑定到不同的生命周期阶段时候,其执行顺序会有生命周期阶段的先后顺序决定的。如果多个目标被绑定到同一个阶段,他们的执行顺序是由插件声明的先后顺序决定目标的执行顺序。

    插件配置

    用户可以配置插件目标的参数,进一步调整插件目标所执行的任务。

    • 命令行插件配置
    如 $mvn install -Dmaven.test.skip=true 的意义即跳过测试步骤。
    参数-D的java自带的,其功能是通过命令行设置一个java系统属性,maven简单地重用了该参数以实现插件参数的配置。
    
    
    • pom中插件全局配置
      如项目编译使用1.6版本的源文件,生成与JVM1.6兼容的字节码文件,如下:
    
    <plugin>  
                    <groupId>org.apache.maven.plugins</groupId>  
                    <artifactId>maven-compiler-plugin</artifactId>  
                    <version>2.3.2</version>  
                    <configuration>  
                        <source>1.6</source>  
                        <target>1.6</target>  
                    </configuration>  
                </plugin>  
    

    获取插件描述信息

    
    $mvn help:describe-Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.1  来获取插件的详细信息
        可以简化为:
        $mvn help:describe-Dplugin=compiler
        如果仅仅描述插件目标的信息,可以加上goal参数:
        $mvn help:describe-Dplugin=compiler-Dgoal=compile
        如果想输出更详细的信息,可以加上detail参数:
        $mvn help:describe-Dplugin=compiler-Ddetail
    
    

    灵活的构建

    一个优秀的构建系统必须足够灵活,应该能够让项目在不同的环境下都能成功构建。maven为了支持构建的灵活性,内置了三大特性,即:属性、profile和资源过滤。

    maven属性

    maven属性分6类:

        1、内置属性:如${basedir}表示项目根目录,${version}表示项目版本
        2、POM属性:用户可以引用pom文件中对应的值。如:
             ${basedir} 项目根目录
             ${project.build.directory} 构建目录,缺省为target
             ${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
             ${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
             ${project.packaging} 打包类型,缺省为jar
             ${project.xxx} 当前pom文件的任意节点的内容 
        3、自定义属性:用户可以在pom的<properties>元素下自定义maven属性。
        4、setting属性:用户可以使用以settings开头的属性引用settings.xml中xml元素的值,如${settings.localRepository}指向用户本地仓库的地址。
        5、java系统属性:maven可以使用当前java系统的属性,如${user.home}指向了用户目录。
        6、环境变量属性:所有环境变量都可以使用以env.开头的属性。如:${env.JAVA_HOE}。
    
    

    资源过滤

    这里所谓的资源:也就就是指src/main/resources和src/test/resources文件下的所有文件,默认情况下,这些文件会被复制到classpath下面,即target/classes下面。
    所谓资源过滤,就是过滤这些文件夹下面的文件里面的内容,看里面的maven变量是否需要替换。默认情况下,只有pom.xml里面的变量才会被替换,资源文件是不会被过滤的,但是可以设置,如下:

    
    <build>  
            <finalName>agentmanager</finalName>  
            <sourceDirectory>src/main/java</sourceDirectory>  
            <resources>  
                <!-- 控制资源文件的拷贝 -->  
                <resource>  
                    <directory>src/main/resources</directory>  
                    <excludes>  
                        <exclude>**/jre.zip</exclude>  
                        <exclude>**/jre.tar</exclude>  
                        <exclude>agentmanager.jsmooth</exclude>  
                        <exclude>assembly.xml</exclude>  
                    </excludes>  
                    <targetPath>${project.build.directory}</targetPath>  
                </resource>  
                <resource>  
                    <directory>src/main/resources/conf</directory>  
                    <targetPath>${basedir}/conf</targetPath>  
                    <filtering>true</filtering>  
                </resource>  
            </resources>  
        </build>  
    

    如jdbc.properties

    
    jdbc.driverClassName=${db.driver}  
    jdbc.url=${db.url}  
    jdbc.username=${db.user}  
    jdbc.password=${db.pwd}  
    

    profile文件

    
    <profiles>  
     <profile>  
      <id>dev</id>  
      <properties>  
       <db.driver>oracle.jdbc.driver.OracleDriver</db.driver>  
       <db.url>jdbc:oracle:thin:@10.252.48.3:1521:dbname</db.url>  
       <db.user>username</db.user>  
       <db.pwd>userpwd</db.pwd>  
      </properties>  
     </profile>  
     <profile>  
      <id>test</id>  
      <properties>  
       <db.driver>oracle.jdbc.driver.OracleDriver</db.driver>  
       <db.url>jdbc:oracle:thin:@10.252.48.3:1521:testdbname</db.url>  
       <db.user>testusername</db.user>  
       <db.pwd>testuserpwd</db.pwd>  
      </properties>  
     </profile>  
    </profiles>  
    

    在构建时可以使用-P参数激活一个或多个profile,多个之间用逗号分隔

    mvn clean install -Pdev
    
    

    maven profile

    上面例子应该可以看出profile是做什么的,其实就相当于定义了一系列的profile变量,在具体构建时可用使用其中的某个profile去变量替换资源文件。
    激活profile的方式有很多,如命令行激活(上面),settings文件显式激活、系统属性激活、操作系统环境激活、默认激活、文件存在与否激活等,具体可以参考官网资料。

    • profile的种类

    根据需要,可以在以下文件声明profile。

    1、pom.xml 针对当前项目
    2、用户 settings.xml 用户目录下的.m2/settings.xml, 对当前用户的所有项目有效。

    3、全局 settings.xml 即maven安装目录下的conf/settings.xml。对本机上的所有项目有效。

    web资源过滤

    在maven的web项目里面,除了上面所说的资源文件(src/main/resources)之外,还有一类叫做web资源目录,即src/main/webapp下面的js、css等等。默认情况下,这些目录是不被资源过滤的,开启的命令如下:

    
      <plugin>  
    
        <groupId>org.apache.maven.plugins</groupId>  
    
        <artifactId>maven-war-plugin</artifactId>  
    
        <version>2.1.1</version>  
    
        <configuration>  
    
            <webResources>  
    
            <resource>  
    
                <directory>src/main/webapp</directory>  
    
                <filtering>true</filtering>  
    
                <includes>  
    
                <include>**/*.css</include>  
    
                <include>**/*.js</include>  
    
                </includes>                            
    
            </resource>      
    
            </webResources>  
    
        </configuration>  
    
    </plugin> 
    
    

    总结

    生命周期是maven定义好的,每个生命周期都有特定阶段的顺序。
    插件能够绑定到特定阶段上,插件完成的事任务目标。
    生命周期分为:clean、default、site

    定位问题原因* 根据原因思考问题解决方案* 实践验证方案有效性* 提交验证结果
  • 相关阅读:
    .net在list列表中查询指定的几条
    【JSP】JSP 标准标签库(JSTL)
    【UI】-LigerUI
    【MySQL】MySQL优化
    【微信小程序】menu
    【微信小程序】login
    【插件】PageHelper实现分页
    《学习javascript数据结构与算法》——第四章:队列
    《学习javascript数据结构与算法》——第三章:栈
    《学习javascript数据结构与算法》——第二章:数组
  • 原文地址:https://www.cnblogs.com/jimoliunian/p/13718333.html
Copyright © 2011-2022 走看看