Maven聚合与继承实例详解
概述
在javaweb高速发展的今天,我们软件设计人员往往会用很多种方式对软件划分模块,目的就是为了能有清晰的设计和低耦合性的,高重用性的软件。Maven有很好的依赖管理系统(Dependency Management System)和项目生命周期的管理(Project Leftcycle),而其中的依赖管理是本文阐述和做出实例的重点。
实例背景
利用一个教程的上面的例子,给大家做讲解。Maven安装有两种方式,一种是直接到Maven官网下载自己电脑的操作系统相应的版本安装,不管是window,linux还是Max os同时官网安装教程也是挺不错的。另外一种是安装eclipse的maven插件,这个很多人都用过,eclipse上面的plugin也是琳琅满目,具体教程网上很多哈。我们今天讲解主要针对后面一种方式,在eclipse进行的搭建Maven项目的操作。对于刚刚接触Maven和不熟悉command行的同学来说,可以是直观的操作,很好。
Maven是apache的一个项目,所以也是源于服务java项目的一个开源工具。所以很多概念也是和java中的基本概念很是相似,比如说继承。我们说java中的父类和子类的关系,子类可以引用父类中非private的变量和方法。反映到Maven项目的搭建也是一样的。Maven中的parent定义的dependency,其中继承者是可以直接使用parent中的Maven Dependencies的。
被继承的Maven项目中的POM的部分定义是
<groupId>com.company</groupId>
<artifactId>company-project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
继承的Maven项目中的POM的关键部分就是
<parent>
<groupId>com.taotao</groupId>
<artifactId>company-project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>company-project-children</artifactId>
操作步骤
-
建立Maven的parent项目
填写group Id和artifact Id和选择Packaging
编辑web-parent中项目的pom文件
其中<modelVersion>、<groupId>、<artifactId>、<version>、<packaging>是创建Maven项目的时候有了,但是<properties>、<dependencyManagement>、<build>中的内容是后面添加的。<dependencyManagement>是定义一个虚拟的资源,这个部分并不直接使用,而<dependencyManagement>中的<dependency>,它的<version>会直接引用到<properties>中的各个resource的版本号。由于<dependencyManagement>中的资源不会直接使用,我们会发现,即使我们定义完这些具体的资源,项目中也没有具体的Maven Dependencies的jar包出现。
<projectxmlns="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>
<groupId>com.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<jackson.version>2.4.2</jackson.version>
<druid.version>1.0.9</druid.version>
<httpclient.version>4.3.5</httpclient.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<joda-time.version>2.5</joda-time.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-io.version>1.3.2</commons-io.version>
<commons-net.version>3.3</commons-net.version>
<pagehelper.version>3.4.2-fix</pagehelper.version>
<jsqlparser.version>0.9.1</jsqlparser.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<jedis.version>2.7.2</jedis.version>
<solrj.version>4.10.3</solrj.version>
</properties>
<!-- 只定义依赖的版本,并不实际依赖 -->
<dependencyManagement>
<dependencies>
<!-- 时间操作组件 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<!-- Apache工具组件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis.paginator.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!-- solr客户端 -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solrj.version}</version>
</dependency>
</dependencies>
</dependencyManagemen>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 资源文件拷贝插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>t>
</project>
这个现象有点像java中interface,定义了变量和方法,但是不会直接使用,得有具体的class来实现。所以我们发现继承了的Maven项目如果在<dependencies>“实现”了parent maven的<dependency>,就会直接的出现改jar包。
当然,如果第一次建立Maven项目,要等待很长时间去maven的网上资源库下载到相应的文件,所以不要着急。
2.创建子项目web-common
创建一个子项目,packagin要选择jar,parent project要选择要继承的maven project。packaging中有三种选项,一种是pom,一种是jar,一种是war。无论选择哪一种,最后都是maven项目,所有都带有pom配置文件。但是jar和war是会有其他一些文件(jar中有libraries, resources and accessories files like property files,而war将会被部署在一些服务容器上面,所以war有jsp, html, javascript and other files necessary )
- web-common的pom的文件会如下
<projectxmlns="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.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
但是我们要添加部分内容
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- Apache工具组件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
- Finish后,我们会看pom和war的Maven项目的不同
- 到这里我们就会讲完了继承的关系了,继续讲解聚合。
现在我们新建一些工程来测试Maven聚合:
一、建立以pom为packaging的项目为,然后再以这一个项目为parent project来聚合其他子项目
- 新建立一个以pom的项目
改写pom文件,依赖web-common,这样就可以将web-common中的jar包都实现过来,这个有点像 java中implement了一个接口后,在实现了吧。我们是packaging为pom的项目,所以也是给准备实现了该maven的project,做好铺垫吧。
<projectxmlns="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.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
所以我们会看到项目的初始文件目录,很简单
二、我们接下来要根据上面建立的项目实现聚合的例子
- 点击web-test这个项目,右键,新建一个maven的module
- 创建一个来存放pojo的module部分,packaging为jar(不要选择pom或者war,具体看上一篇)
- 点击finish
- 这个时候,我们会发现web-test中的pom文件多了下面的内容
<modules>
<module>web-test-pojo</module>
</modules>
- 说明我们把web-test-pojo已经聚合到web-test中去了。
- 同时web-test-pojo的内容是继承了web-common中的部分内容,而web-test-pojo的pom其实是不用修改的。
三、同时我们再建立以web-test为基础的web-test-mapper和web-test-service的module,这个和步骤二是一模一样的,唯一有区别的地方就是建立完后要在pom文件中加入每个模块自己单独需要的dependencies。另外一个就是web-test-mapper是依赖于web-test-pojo,所以web-test-mapper中的dependencies是含有web-test-pojo的dependency,而web-test-service则是依赖于web-test-mapper。所以下面将展示web-test-mapper和web-test-service的pom文件。
web-test-mapper的pom文件如下:
<projectxmlns="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.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-mapper</artifactId>
<!-- 依赖管理 -->
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
</project>
web-test-service的pom文件
<projectxmlns="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.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-service</artifactId>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-mapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</dependencies>
</project>
四、建立以war为基础的Maven项目,我们之前已经建立了三个以web-test为parent的Maven的jar的模块,但是要发布一个web项目,必须是有war包,war中才含有文件夹来存放前端的js,jsp等文件啦。和上面一样,在web-test上面创建module,不同的是,创建的packaging是war
- 创建一个module
- 选择war
- 在pom文件中加入自己想要的dependency
<projectxmlns="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.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test-web</artifactId>
<packaging>war</packaging>
<!-- 依赖管理 -->
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-test-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
</dependencies>
</project>
五、此时,我们可以看到web-test其实已经聚合四个module,四个module在web-test的基础建立起来,但是他们又是一个整体,所以,当项目发布的时候,其实以web-test为单位的。
<projectxmlns="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.company</groupId>
<artifactId>web-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>web-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<modules>
<module>web-test-pojo</module>
<module>web-test-mapper</module>
<module>web-test-service</module>
<module>web-test-web</module>
</modules>
</project>
六、其实到了这里,我们就把一个项目的聚合和模块被聚合的例子讲完了,但是如果要跑这个项目也是可以的。
- 在web-test中pom的文件加入以下内容,将tomcat的插件配置到web-test中去
<build>
<!-- 配置插件 -->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
- 另外在,web-parent和web-common安装到本地的仓库中去
在web-parent项目上面右键,然后run as
- 然后在goal 填入install
- 同样的步骤在web-common项目执行
- 执行后,在web-test这个主项目中run下面的代码 clean tomcat7:run
最后就可以登陆看web-test中的首页了,继承与聚合实例测试完成。
上一篇: 数据结构与算法之队列(基于数组)讲解
推荐阅读
-
解析C#自定义控件的制作与使用实例的详解
-
详解IOS串行队列与并行队列进行同步或者异步的实例
-
Struts2拦截器Interceptor的原理与配置实例详解
-
解析C#中委托的同步调用与异步调用(实例详解)
-
Android style的继承方式 点(.)和parent详解及实例
-
Maven dependencies与dependencyManagement的区别详解
-
iOS UITableView 与 UITableViewController实例详解
-
Python基础学习之类与实例基本用法与注意事项详解
-
Maven2环境安装与准备工作详解
-
spring boot+vue 的前后端分离与合并方案实例详解