闲来无事,思量着自己搭建一个ssh框架,一来回顾熟悉一下ssh的内容,hibernate还就没用过了,生疏了都。二来整合一下,将其他掌握的和正在学习的框架核技术糅合到一起,就当是做一个demo练手了。
首先要把最基层的ssh框架运行起来,利用maven来构建,设想的是将业务分为多个模块,各个模块之间相互独立,甚至每个模块可以独立运行。查询若干资料可以利用maven创建model,然后整合为一个项目,今天先介绍一下基于maven的多模块项目搭建。
多模块其实就是按照层级的管理构建,项目包含一个pom.xml文件和若干个模块,每个模块有一个单独的pom.xml文件,通过pom的依赖和继承关系来构建项目层次。废话不多说,文采也不好,就直奔主题吧,首先贴一张项目结构图:
从上图中可以清楚的看到模块与项目以及模块与模块之间的层级关系,解释一下为什么这么分模块:
web模块存放的是客户端资源,包括js,css,以及jsp等。其他各模块为业务模块,common为公共模块,其中封装了公用的util工具类以及常量等。
打包方式为项目采用pom方式,业务模块打成jar,web模块打包成war包,最后的war包只包括web模块下的资源,其他业务模块以jar形式存在war包中WEB-INF/lib文件夹下
。
1、创建maven项目
Maven的安装和配置就不细说了,打开eclipse首先新建一个maven项目,删除src目录(项目中是没有代码的,所有的代码都是在各个模块中编写的),将buildpath中的source文件夹给remove掉,并将output文件夹修改到web模块下web-inf/classes文件夹下(没有则新建)。如下图所示:
打开pom.xml文件,添加或修改代码 :
<packaging>pom</packaging>
将项目的打包方式修改为pom方式,然后添加ssh相关的dependency和plugins等内容。
2、maven项目添加model
在项目上右键,新建选择maven model:
输入model名称,next配置sshFrame和groupId完成后可以看到工作空间中多了一个项目,打开模块pom文件,稍作修改:
重点关注parent标签,其配置的是该模块所属的父级项目,这里当然配置顶级的项目了,子模块的pom文件是继承字父级的pom文件的,所以在父级pom中定义的dependencies在子模块中可以直接引用,模块的属性也只需定义一个artifactId就可以了,groupId和version可以从父级继承,relativePath配置是父级pom.xml文件的相对路径,一般可以省略,不过有时会报错,说找不到父级pom,所以就干脆加上了。
这时候再次打开项目的pom.xml文件可以发现其中多了一个modules标签,其中内容就是刚刚新建的模块的artifactId。
其他模块的新建依此类推,过程是完全一样的。
3、编译以及运行
模块建立完成后,运行项目的pom文件,run as mvn install 下载jar,运行命令mvn compile进行编译,编译后可以在各个模块的target文件夹下看到编译后的class文件,web模块的输出路径最好也给改成web-inf/classes下。编译通过后就可以启动tomcat进行测试了,我使用的是tomcat插件,需要先进行配置。配置图如下:
打开tomcat中server.xml文件,添加context。
启动tomcat后访问localhost:8080/ssh/user/toUserIndex.action即可查看到页面效果了,该页面访问的是User模块的action。
4、问题以及解决方案
在搭建过程中出现了各种各样的错误,也一直在摸索着前进,总结一下出现的问题和解决办法。
(1) tomcat启动后不能加载到其他模块的代码,只加载到了web模块。
答:运行mvn compile编译后生成的class文件都是在各自模块的target目录下的,需要在tomcat配置中需要加载的模块勾上,如下图:
这样再启动tomcat就会加载到class文件了。
(2)、strus文件无法引入其他模块的struts_user.xml文件
答:struts可以使用include命令包含其他的配置文件file属性为文件的地址
<include file="struts_config/struts_user.xml"></include>
这样是可以正确加载文件的,注意struts_config前面是没有”/”的。
(3)、模块之间相互依赖的问题
项目过大,模块过多的话可能多个模块之间会存在相互依赖的关系,如下图:
这样使用maven编译不能通过,要解决循环依赖有两种解决办法,一种就是重构代码,从根本上解决依赖的问题。还有一种折中的办法,使用build-helper-maven-plugin解决相互依赖的问题我的解决办法就是先把相互依 赖的模块整合在一起,相当于把这些模块合并成一个单独的模块统一编译。
依赖关系转换为多对一的关系,如下图:
要想把A、B、C三个模块整合在一起编译,需要借助build-helper-maven-plugin插件 ,这个插件在Maven构建周期提供一些辅助功能,下面列出插件的提供的功能列表: build-helper:add-source:添加更多的构建源码目录 build-helper:add-test-source:添加更多的测试源码目录 build-helper:add-resource:添加更多的资源目录 build-helper:add-test-resource:添加更多的测试资源目录 build-helper:attach-artifact:在安装和部署周期附加artifacts build-helper:maven-version:添加一个指定当前Maven版本的属性 build-helper:parse-version:添加一个指定组件版本的属性 build-helper:released-version:决定当前项目的最终版本 build-helper:remove-project-artifact:从本地资源库中移除项目的artifacts build-helper:reserve-network-port:Reserve a list of random and unused network ports. 在这里我们要用到build-helper:add-source这个功能,将模块A、B、C的源码路径加 进来。 我们再添加一个辅助模块D,在辅助模块D中使用build-helper-maven-plugin插件,然 后让模块A、B、C都依赖于辅助模块D,模块D的POM模型如下:
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <relativePath>../pom.xml</relativePath> <artifactId>sshFrame</artifactId> <groupId>org.lslvxy.sshFrame</groupId> <version>${project.version}</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>sshFrame-pack</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <module.common.src>../sshFrame-common/src/main/java</module.common.src> <module.user.src>../sshFrame-user/src/main/java</module.user.src> <module.role.src>../sshFrame-role/src/main/java</module.role.src> </properties> <build> <resources> <resource> <directory>../sshFrame-common/src/main/resources</directory> </resource> <resource> <directory>../sshFrame-user/src/main/resources</directory> </resource> <resource> <directory>../sshFrame-role/src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${module.common.src}</source> <source>${module.user.src}</source> <source>${module.role.src}</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
这样就生成了一个模块pack,将其他模块的源代码和resource编译到pack模块中,然后其他模块依赖这一个pack模块,启动tomcat时加载pack模块和web模块即可正常启动项目。
5、总结
至此,一个简单的maven多模块项目就搭建成功了,也可以正常的运行和访问。
不过需要完善和丰富内容还需要一部分工作。源代码:
这个源码中包含了jquery easyui做的界面,也才刚刚开始做了一部分。
文采不好,写的很乱,如果有什么问题的话可以给我留言或者qq我。
--本篇完--