MAVEN中项目构建的一些概念和思想

 一、Maven的基础知识回顾

        官网的英文介绍:          

Maven, a Yiddish word meaning accumulator of knowledge, began as an attempt to simplify the build processes in the Jakarta Turbine project. There were several projects, each with their own Ant build files, that were all slightly different. JARs were checked into CVS. We wanted a standard way to build the projects, a clear definition of what the project consisted of, an easy way to publish project information and a way to share JARs across several projects.

The result is a tool that can now be used for building and managing any Java-based project. We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project.

        中文翻译:

      Maven这个单词来自于意第绪语(犹太语),意为知识的积累,最初在Jakata Turbine项目中用来简化构建过程的一种尝试。当时有一些项目(有各自Ant build文件),仅有细微的差别,而JAR文件都由CVS来维护。于是希望有一种标准化的方式构建项目,一个清晰的方式定义项目的组成,一个容易的方式发布项目的信息,以及一种简单的方式在多个项目中共享JARs。

        自己理解:

        Maven:说白了就是jar包的管理工具,通过提供一些多功能的插件,来快速方便快捷的构建我们的项目,通过以pom文件为核心,每个maven项目都有自己的pom文件。pom文件和pom文件可以通过module和parent标签来建立父子关系,同一个父项目下的module可以使用dependency来进行相互引用(前提:所有的项目的都已经上传到本地仓库了)

       仓库的种类:本地仓库,远程仓库【私服】,中央仓库

       仓库之间的关系:当我们启动一个maven工程的时候,maven工程会通过pom文件中jar包的坐标去本地仓库找对应jar包。
       默认情况下,如果本地仓库没有对应jar包,maven工程会自动去中央仓库下载jar包到本地仓库。 在公司中,如果本地没      有对应jar包,会先从私服下载jar包,如果私服没有jar包,可以从中央仓库下载,也可以从本地上传。

        一键构建:maven自身集成了tomcat插件,可以对项目进行编译,测试,打包,安装,发布等操作。

二、Maven主要结构介绍

      首先我以一个父项目pom文件为例:

      父项目的pom文件主要是做件事:

              1.定义项目基本内容的设置

    <groupId>com.xxxx</groupId>
    <artifactId>econtract-service-test</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

            groupId:项目或者组织的唯一标志 ,一般来说都是公司的域名转置写法

            artifactId:项目的通用名称

            version:项目的版本 SNAPSHOT:快照版 REALEASE:正式版

            packaging:打包机制,如pom,jar,maven-plugin,ejb,war,ear,rar,par

            2.添加子模块

  <modules>
        <!-- 根据你的业务需求定义不同的模块 如 dao api config等等-->
        <module>这里的名称是与子模块中的<artifactId/>中的值一致</module>
        <module>econtract-dao</module>
        <module>econtract-api</module>
        <module>econtract-api-test</module>
    </modules>

          3.添加文件的常量定义区,在文件中可以直接引用,如版本,编码,配置文件的目录等等

<properties>
  <file.encoding>UTF-8</file_encoding>
  <java.source.version>1.8</java_source_version>
  <java.target.version>1.8</java_target_version>
  <mysql.version>5.1.46</mysql.version>
  <restassured.version>3.3.0</restassured.version>
  <aspectj.version>1.8.10</aspectj.version>
  <spring.starter.version>2.1.6.RELEASE</spring.starter.version>
  <generated.sources>${project.build.directory}/generated-sources</generated.sources> 
  <application.config>classpath:application-${spring.profiles.active}.yml</application.config>
</properties>

     4.添加项目加载时需要激活的配置文件这里需要对应的插件一起配合使用

  <profiles>
        <profile>

             <!--不同环境Profile的唯一id-->
            <id>dev</id>

            <properties>
            <!--profiles.active是自定义的字段(名字随便起),自定义字段可以有多个-->
                <spring.profiles.active>dev</spring.profiles.active>
            </properties>

             <!--activation用来指定激活方式,可以根据jdk环境,环境变量,文件的存在或缺失-->
            <activation>
                <!--这个字段表示默认激活-->
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
    </profiles>

     对应使用的插件

//简单解释一下,网上大部分都是读取properties配置文件的插件,我这个是读yaml文件的,用法基本上是差不多的
                <plugin>
                    <groupId>it.ozimov</groupId>
                    <artifactId>yaml-properties-maven-plugin</artifactId>
                    <version>1.1.3</version>

//执行的操作集
                    <executions>
                        <execution>
                            <phase>initialize</phase>
                            <goals>
                                <goal>read-project-properties</goal>
                            </goals>

//这里的${application.config}就是在properties标签已经定义好的全局变量
                            <configuration>
                                <urls>
                                    <url>${application.config}</url>
                                </urls>
                            </configuration>
                        </execution>
                    </executions>

//因为是使用的多模块构建项目所以这里是需要将配置模块的依赖引进来,所以这个 <url>${application.config}</url>是对应与econtract-conf的相对路径
                    <dependencies>
                        <dependency>
                            <groupId>com.xforceplus</groupId>
                            <artifactId>econtract-conf</artifactId>
                            <version>${project.version}</version>
                        </dependency>
                    </dependencies>
                </plugin>

主要流程:a.yaml-properties-maven-plugin启动时会先加载 econtract-conf 模块该模块里面都是配置文件包括:prod,fat,dev。

b.通过<url>指定文件相对于 econtract-conf 模块的路径一般都是类路径 ${application.config}定义在properties中:

<application.config>classpath:application-${spring.profiles.active}.yml</application.config>

c.通过profile标签来指定整个项目激活的是哪个文件

           <properties>
            <!--profiles.active是自定义的字段(名字随便起),自定义字段可以有多个-->
                <spring.profiles.active>dev</spring.profiles.active>
            </properties>

 所以最后激活的文件就是econtract-conf的classpath:application-dev.yml

5.配置jar包管理dependencyManagement 和 插件管理pluginManagement

<dependencyManagement>
        <dependencies>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
                <scope>runtime</scope>
            </dependency>
      
            <!--swagger-->
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>1.5.22</version>
            </dependency>
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>2.0.1.Final</version>
            </dependency>

            <!--jackson-->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.9.9</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.9.3</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.9.9</version>
            </dependency>

            <!--fastjson-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.51</version>
            </dependency>

            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.0</version>
            </dependency>
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.1.8</version>
            </dependency>

            <!--test-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring.starter.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.14.3</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>3.11.1</version>
                <scope>test</scope>
            </dependency>
     
        </dependencies>
    </dependencyManagement>

插件管理:

<pluginManagement>
            <plugins>
                <plugin>
                    <groupId>it.ozimov</groupId>
                    <artifactId>yaml-properties-maven-plugin</artifactId>
                    <version>1.1.3</version>
                    <executions>
                        <execution>
                            <phase>initialize</phase>
                            <goals>
                                <goal>read-project-properties</goal>
                            </goals>
                            <configuration>
                                <urls>
                                    <url>${application.config}</url>
                                </urls>
                            </configuration>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>com.xforceplus</groupId>
                            <artifactId>econtract-conf</artifactId>
                            <version>${project.version}</version>
                        </dependency>
                    </dependencies>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>build-helper-maven-plugin</artifactId>
                    <version>3.0.0</version>
                    <executions>
                        <execution>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>add-source</goal>
                            </goals>
                            <configuration>
                                <sources>
                                    <source>${generated.sources}</source>
                                </sources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <encoding>${file.encoding}</encoding>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                        <!--<compilerArgument>-Werror</compilerArgument>-->
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>3.0.1</version>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <goals>
                                <goal>jar-no-fork</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <version>3.0.1</version>
                    <executions>
                        <execution>
                            <id>attach-javadocs</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                            <configuration>
                                <charset>${file.encoding}</charset>
                                <encoding>${file.encoding}</encoding>
                                <docencoding>${file.encoding}</docencoding>
                                <additionalOptions>
                                    <additionalOption>-Xdoclint:none</additionalOption>
                                </additionalOptions>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

这里解释下父项目是整个项目的leader,在父pom文件中我们只需要定义该项目需要的依赖的版本信息和插件的使用细则,但是具体的加载真正使用是交给子模块去完成。

dependencyManagement标签详解:

在父项目的POM文件中,我们会使用到dependencyManagement元素。通过它来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在dependencyManagement元素中指定的版本号。

<dependencyManagement>
        <dependencies>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                //定义在properties中的信息
                <version>${mysql.version}</version>
                <scope>runtime</scope>
            </dependency>
</dependencyManagement>

如果不写dependencyManagement直接使用dependencies就相当于是直接引入依赖

相对于dependencyManagement,父类中直接使用所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。如果依赖只在某个子项目中使用,则可以在子项目的pom.xml中直接引入,防止父pom的过于臃肿。

最后一点:

        dependencies与dependencyManagement 区别总结

1、dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)

2、dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。


        注意事项:依赖范围对传递依赖的影响

因为依赖会有依赖范围,依赖范围对传递依赖也有影响,例如有 A、B、C,A 依赖 B、B依赖 C,C可能是 A的传递依赖,如下图:

最左边一列为直接依赖,理解为 A 依赖 B 的范围,最顶层一行为传递依赖,理解为 B依赖 C 的范围,行与列的交叉即为 A传递依赖 C的范围

举例 1:
               比如 A 对 B 有 compile 依赖,B 对 C 有 runtime 依赖,那么根据表格所示 A 对 C 有runtime 依赖。那么C确实是被依赖进来了。

但是,假设我们有一个xxx_dao的模块依赖junit,scope 为test,同时也有一个xxx_service依赖xxx_dao,如果此时我们在xxx_service中做单元测试是无法成功的,因为我们所需要的junit这个依赖根本没有传递进来,原因如下图所示        

对应得到的传递依赖范围为空,所以根本没传递进来,这点需要注意,解决办法,在模块的pom文件直接添加所需要的依赖。

pluginManagemen标签的配置:

pluginManagement的作用类似于denpendencyManagement,只是denpendencyManagement是用于管理项目jar包依赖,pluginManagement是用于管理plugin。样例如下:

<pluginManagement> 
  <plugins> 
    <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-jar-plugin</artifactId> 
      <version>2.2</version> 
      <executions> 
        <execution> 
          <id>pre-process-classes</id> 
          <phase>compile</phase> 
          <goals> 
            <goal>jar</goal> 
          </goals> 
          <configuration> 
            <classifier>pre-process</classifier> 
          </configuration> 
        </execution> 
      </executions> 
    </plugin> 
  </plugins> 
</pluginManagement> 

与pom build里的plugins区别是,这里的plugin是列出来,然后让子pom来决定是否引用

子pom引用方法: 在pom的build里的plugins引用

<plugins> 
  <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-jar-plugin</artifactId> 
  </plugin> 
</plugins>

三、Maven父子工程之间的关系

Maven中
          工程和模块的区别:
          工程不等于完整的项目,模块也不等于完整的项目,一个完整的项目看的是代码,代码完整,就可以说是一个完整的项目
时和此项目是工程和模块没有关系

工程天生只能使用自己内部的资源,工程是独立的。后天可以和其他工程或模块建立关联关系。

模块天生不是独立的,模块天生是属于父工程的,模块一旦创建,所有父工程的资源都可以使用。

jar包本质上就是代码块
         父子工程之间,子模块天生集成父工程,可以使用父工程所有的资源
         子模块之间天生是没有任何关系的,如果需要使用其它模块的功能,只需要当成普通依赖引入jar包

父子工程之间不用建立关系,继承关系是先天的,不需要手动建立
           平级之间的引用叫依赖,依赖不是先天的,依赖是需要后天建立的

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值