建立parent工程

属性节点

properties,在这一节点下,定义变量。有一些工程相关的变量:

<properties>
  <java_source_version>1.8</java_source_version>
  <java_target_version>1.8</java_target_version>
  <file_encoding>UTF-8</file_encoding>
  <project.build.sourceEncoding>${file_encoding}</project.build.sourceEncoding>
  <spring_version>4.3.8.RELEASE</spring_version>
</properties>

其中
project.build.sourceEncoding 属性会被eclipse读取,在初始化工程时指定文件编码。
java_source_versionjava_target_version在结合maven-compiler-plugin插件配置,会被eclipse读取,在初始化工程时指定编译jdk版本。

依赖的统一管理

dependencyManagement节点中统一各项目中依赖库的版本,可以结合properties更统一的更新版本号;

<dependencyManagement>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring_version}</version>
  </dependency>
</dependencyManagement>

这样在继承parent工程的子工程中,引入该依赖库时不用再次定义version了。
还可以预先处理依赖库中不必要的依赖冲突,比如使用log4j2时,屏蔽其他库依赖的日志组件:

<dependency>
  <groupId>com.101tec</groupId>
  <artifactId>zkclient</artifactId>
  <version>${zkclient_version}</version>
  <exclusions>
    <exclusion>
      <artifactId>slf4j-api</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
    <exclusion>
      <artifactId>slf4j-log4j12</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j</artifactId>
      <groupId>log4j</groupId>
    </exclusion>
  </exclusions>
</dependency>

插件统一管理

类似的,还有maven插件包括版本在内的一些参数设置,在pluginManagement节点。

<pluginManagement>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven_compiler_plugin_version}</version>
    <configuration>
      <fork>true</fork>
      <source>${java_source_version}</source>
      <target>${java_target_version}</target>
      <encoding>${file_encoding}</encoding>
    </configuration>
  </plugin>
</pluginManagement>

仓库定义

发布库路径的管理,在distributionManagement节点。

<distributionManagement>
   <repository>
      <id>nexus-repos-releases</id>
      <url>http://xxx.xx/nexus/content/repositories/releases</url>
    </repository>
  <snapshotRepository>
      <id>nexus-repos-snapshots</id>
      <url>http://xxx.xx/nexus/content/repositories/snapshots</url>
   </snapshotRepository>
  </distributionManagement>

仓库的配置,一般是私有库地址配置,在repositories节点,这个优先级高于maven的setting.xml中的全局定义。

<repositories>
    <repository>
      <id>nexus-repos</id>
      <url>http://xxx.xx/nexus/content/groups/public/</url>
    </repository>
</repositories>

建立其他模块工程

注意,虽然我们把项目划分为子模块,但是不一定是maven意义上的module。
用eclipse创建Maven Module类型工程时,都建在solo-parent目录下,为子模块工程,无法独立打包。

建一个类型为Maven Project类型的工程,名称solo-api,parent是solo-parent。

solo-parent的pom.xml 会被自动上modules节点

<groupId>com.code1024</groupId>
  <artifactId>solo-parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <modules>
  	<module>solo-api</module>
  </modules>

solo-api的pom.xml 会有parent节点

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.code1024</groupId>
    <artifactId>solo-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

  <artifactId>solo-api</artifactId>

</project>

创建Maven Project类型则会在solo-parent平级的位置建立独立工程目录。
在引入solo-parent的pom时,使用relativePath属性,优先去该路径读取parent的pom.xml,否则从仓库下载。
这样的工程时可以独立打包的,如果需要同时打包很多模块工程,可以建立一个聚合工程。

比如建一个solo-all来打包所有的模块。
pom.xml的部分内容如下:

<parent>
    <groupId>com.code1024</groupId>
    <artifactId>solo-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../solo-parent/pom.xml</relativePath>
  </parent>
  
  <artifactId>solo-all</artifactId>
  <packaging>pom</packaging>
  <name>solo-all</name>

  <modules>
    <module>../solo-api</module>
    <module>../solo-core</module>
    <module>../solo-web</module>
  </modules>

特殊的依赖集合工程

有一些组件需要较多的三方依赖包,但是又不是每一个工程都会用到。
这个时候,用一个pom工程把一组依赖包集合归到一起,方便需要的工程引入,统一管理和升级;

比如,建议一个使用mysql的数据访问依赖集合solo-mysql工程。

pom.xml的部分内容如下:

<parent>
    <groupId>com.code1024</groupId>
    <artifactId>solo-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../solo-parent/pom.xml</relativePath>
  </parent>

  <artifactId>solo-mysql</artifactId>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
    </dependency>
  </dependencies>

多模块中单独打包某一模块

在eclipse中,多模块项目中单独打包某个web工程时,选中 “resolve workspace artifacts” 会导致war包内依赖的其他模块的jar为空目录。

正确的打包某个模块的方式是在parent工程上运行 Run As… > Maven Build…,在Goals中输入:

clean package -pl module_name -am

多模块工程的打包命令参考:

-am --also-make 同时构建所列模块的依赖模块;
 -amd -also-make-dependents 同时构建依赖于所列模块的模块;
 -pl --projects <arg> 构建制定的模块,模块间用逗号分隔;
 -rf -resume-from <arg> 从指定的模块恢复反应堆。

看英文的更助于理解:

-am,--also-make

If project list is specified, also build projects required by the list

-amd,--also-make-dependents

If project list is specified, also build projects that depend on projects on the list

-pl,--projects <arg>

Comma-delimited list of specified reactor projects to build instead of all projects. A project can be specified by [groupId]:artifactId or by its relative path.

-rf,--resume-from <arg>

Resume reactor from specified project