`
123003473
  • 浏览: 1064125 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

解决Maven项目相互依赖/循环依赖/双向依赖的问题

 
阅读更多
很​多​时​候​随​着​项​目​的​膨​胀​,模​块​会​越​来​越​多​,如​果​设​计​上​ 稍​有​不​慎​就​会​出​现​模​块​之​间​相​互​依​赖​的​情​况​。​这​对​于​使​用​Maven的​用​户​是​比​较​痛​苦​的​,因​为​出​现​模​块​之​间​相​互​依​赖​的​话​在​构​建​的​时​候​就​会​失​败​,Maven通​常​要​先​编​译​被​依​赖​的​模​块​,如​果​出​现​相​互​依​赖​Maven就​不​知​道​该​怎​么​办​了​。​下​图​描​述​了​三​个​Maven模​块​相​互​依​赖​的​场​景​: 

图 1. A、​B、​C三​个​模​块​相​互​依​赖​


图​中​模​块​C依​赖​于​模​块​B,模​块​B依​赖​于​模​块​A,而​模​块​A又​依​赖​于​模​块​C,这​样​就​出​现​了​相​互​依​赖​情​况​,如​果​运​行​mvn compile会​出​现​如​下​错​误​:
[INFO] Scanning for projects... [ERROR] The projects in the reactor contain a cyclic reference: Edge between 'Ve rtex{label='org.kuuyee.sample:module-C:1.0-SNAPSHOT'}' and 'Vertex{label='org.ku uyee.sample:module-B:1.0-SNAPSHOT'}' introduces to cycle in the graph org.kuuyee .sample:module-B:1.0-SNAPSHOT --> org.kuuyee.sample:module-A:1.0-SNAPSHOT --> or g.kuuyee.sample:module-C:1.0-SNAPSHOT --> org.kuuyee.sample:module-B:1.0-SNAPSHO T -> [Help 1][ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit ch.[ERROR] Re-run Maven using the -X switch to enable full debug logging.[ERROR] [ERROR] For more information about the errors and possible solutions, please rea d the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectCycleEx ception
1. 使​用​build-helper-maven-plugin解​决​相​互​依​赖​的​问​题​我​的​解​决​办​法​就​是​先​把​相​互​依​赖​的​模​块​整​合​在​一​起​,相​当​于​把​这​些​模​块​合​并​成​一​个​单​独​的​模​块​统​一​编​译​,
如​下​图​:图 2. 合​并​A、​B、​C三​个​模​块​为​D模​块​


这​样​就​产​生​了​一​个​合​并​模​块​D,我​们​把​它​当​做​一​个​辅​助​构​建​模​块​,然​后​让​A、​B、​C模​块​都​依​赖​于​D模​块​,这​样​的​话​就​可​以​成​功​编​译​A、​B和​C模​块​,
如​下​图​: 图 3. 基​于​D模​块​来​分​别​编​译​A、​B、​C三​个​模​块​

要​想​把​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模​型​如​下​: 例 1. 辅​助​模​块​D的​POM模​型​
<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>
		<groupId>org.kuuyee.sample</groupId>
		<artifactId>sample-parent</artifactId>
		<version>1.0-SNAPSHOT</version>
		<relativePath>../../pom.xml</relativePath>
	</parent>
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.kuuyee.sample</groupId>
	<artifactId>module-D</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>module-D</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>
			UTF-8
		</project.build.sourceEncoding>
		<module.a.src>../../module/module-A/src/main/java</module.a.src>
		<module.b.src>../../module/module-B/src/main/java</module.b.src>
		<module.c.src>../../module/module-C/src/main/java</module.c.src>
	</properties>
	<build>
		<plugins><!-- 解决模块相互依赖,综合所有相互依赖代码统一编译 -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>build-helper-maven-plugin</artifactId>
				<executions>
					<execution>
						<id>add-source</id>
						<phase>generate-sources</phase>
						<goals>
							<goal>add-source</goal>
						</goals>
						<configuration>
							<sources>
								<source>${module.a.src}</source>
								<source>${module.b.src}</source>
								<source>${module.c.src}</source>
							</sources>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

【转载地址】http://www.blogjava.net/kuuyee/archive/2011/06/28/353158.html

maven处理循环依赖
 在多maven工程的项目里,如果工程间存在循环依赖,构建就会报错。本文介绍一下循环依赖要怎么处理
  
  1、什么是循环依赖
  
  如果工程A依赖工程B,工程B又依赖工程A,就会形成循环依赖。或者A依赖B,B依赖C,C依赖A,也是循环依赖
  
  总的来说,在画出工程依赖图之后,如果发现工程间的依赖连线形成了一个有向循环图,则说明有循环依赖的现象
  
  如果循环依赖发生在工程之间,则会影响构建,因为maven不知道应该先编译哪个工程。如果循环依赖发生在同一个工程的模块之间,虽然不影响编译,但是也是一种不好的实践,说明模块的设计有问题,应该避免
  
  如果在模块内部,有几个类互相调用的话,我觉得可能是正常的。比如观察者模式里面,Observer和Observable就是互相依赖的
  
  2、怎么解决循环依赖
  
  目前知道有2个办法可以解决
  
  第一个办法是用build-helper-maven-plugin插件来规避。比如A依赖B,B依赖C,C依赖A的情况。这个插件提供了一种规避措施,即临时地将工程A、B、C合并成一个中间工程,编译出临时的模块D。然后A、B、C再分别依赖临时模块D进行编译
  
  这种方法可以解决无法构建的问题,但是只是一个规避措施,工程的依赖关系依然是混乱的
  
  第二个办法是通过重构,从根本上消除循环依赖
  
  3、如何重构
  
  目前也知道2个重构的思路
  
  第一个办法是平移,比如A和B互相依赖,那么可以将B依赖A的那部分代码,移动到工程B中,这样一来,B就不需要继续依赖A,只要A依赖B就可以了,从而消除循环依赖
  
  第二个办法是下移,比如A和B互相依赖,同时它们都依赖C,那么可以将B和A相互依赖的那部分代码,移动到工程C里,这样一来,A和B相互之间都不依赖,只继续依赖C,也可以消除循环依赖
  
  这两种重构方式都是可行的,具体采用哪种方式要根据实际情况来判断。不管采取哪种方式,都需要对代码进行修改,有时候并不是那么容易的

【转载地址】http://www.kaifajie.cn/kaifa_qita/7063.html
分享到:
评论
6 楼 winhbb 2017-11-06  
我刚好遇到了一个问题(在可以依赖注入的场合有效):
有两个模块A和B,当前B已经依赖了A,但是由于之前设计的不合理,导致目前A又需要使用B中的相关方法,目前我临时采取的措施是,在A中定义一个接口,由于B依赖A,所以B可以直接实现该接口,然后A中通过接口声明并注入B中的实例即可。
5 楼 ganbo 2016-08-25  
总结的好,文章给力。
4 楼 q63176347 2015-12-18  
谢谢,需要这篇文章太久了
3 楼 小白941条狗 2015-09-16  
感谢分享,有没有一种方式可以,即保证模块互相独立,又能解决相互依赖产生的问题
2 楼 bughope 2014-04-25  
学习下
1 楼 刚开始吧 2013-05-23  
顶,哥们。文章很给力。

相关推荐

    基于Springboot人力资源管理系统设计毕业源码案例设计.zip

    《基于Springboot的人力资源管理系统设计》 在现代企业中,人力资源管理是至关重要的组成部分,它涉及到员工招聘、培训...此外,这还是一个绝佳的实践平台,可以锻炼你的问题解决能力、代码调试技巧以及团队协作经验。

    cnn-bi-lstm-eclipse安装demo

    在本文中,我们将深入探讨如何在Eclipse集成开发环境中(IDE)安装CNN-Bi-LSTM-Eclipse演示项目。...同时,不断学习和理解CNN、LSTM以及注意力机制的原理,将有助于你更好地利用这个项目来解决问题。

    毕设项目:基于springboot+angularjs实现的旅游业务管理系统.zip

    - `pom.xml`:Maven项目配置文件,定义了依赖和构建过程。 学习这个项目,开发者可以深入理解SpringBoot后端开发和AngularJS前端开发的实践,同时提升项目管理和协作能力。此外,对于毕业设计或课程设计而言,它...

    基于SpringBoot + vue + Element-UI 搭建的个人博客系统.zip

    - `pom.xml`: Maven项目的配置文件,定义依赖和构建过程。 - `.gitignore`: Git版本控制的忽略文件列表。 - `README.md`: 项目说明文档。 这个项目提供了从后端到前端的完整流程,涉及SpringBoot的RESTful API...

    硕士研究生工程实训项目全栈:Pink招聘系统(使用SpringBoot+Vue.js技术).zip

    - **跨域处理**:使用SpringBoot的CORS配置,解决前后端跨域问题。 - **状态码处理**:后端返回HTTP状态码,前端根据状态码判断请求结果并做出相应反馈。 通过这个项目,学生能够深入理解SpringBoot后端开发和Vue....

    基于Java的外卖点餐网站java+springboot+mysql+vue开发的外卖点餐系统、订餐平台 - 毕业设计.zip

    - 自动配置:SpringBoot会根据项目依赖自动配置相应的bean。 - 嵌入式Servlet容器:如Tomcat、Jetty,无需单独部署。 - Starter POMs:简化Maven配置,提供了一组可选的依赖集合。 - Actuator:提供健康检查、指标、...

    nettyWebSocket.rar

    3. **Pom.xml**:这是Maven项目的配置文件,包含项目依赖。在这里,应该列出了Netty库和其他可能的依赖,如WebSocket的相关库,如`netty-all`或单独的WebSocket模块。 4. **src**:源代码目录,通常包含Java源文件...

    springboot+thymeleaf+websocket

    起步依赖是Spring Boot通过Maven或Gradle插件提供的,简化了添加依赖的过程。Actuator提供了健康检查、指标、审计跟踪等功能,便于监控和管理应用。 2. **Thymeleaf** Thymeleaf允许开发者用自然的HTML来编写模板...

    springboot资料springboot资料

    每个起步依赖都是一个包含相关依赖的Maven或Gradle模块,例如`spring-boot-starter-web`用于构建Web应用,`spring-boot-starter-data-jpa`用于数据库访问。 2. **自动配置(Auto Configuration)**:SpringBoot的...

    基于SSM+vue框架的个人博客网站.zip

    1. 项目结构:SSM项目通常遵循Maven或Gradle的目录结构,Vue.js项目则按照SPA(Single Page Application)模式组织。两者需通过前后端分离的方式协同工作。 2. 开发环境:使用IDEA或Eclipse等Java IDE,配合VSCode...

    基于ssm+vue网上商城系统.zip

    6. **构建工具配置**:如Maven或Gradle的pom.xml或build.gradle文件,用于项目构建和依赖管理。 7. **微信小程序**:相关的小程序源代码,包括json、wxml、wxss、js文件,以及微信开发者工具的配置文件。 学习这个...

    JavaEE

    这可以帮助开发者更好地调试和优化代码,提升问题解决能力。 "工具"则指的是JavaEE开发中常用的工具,如集成开发环境(IDE)如Eclipse、IntelliJ IDEA,版本控制系统如Git,构建工具如Maven或Gradle,以及持续集成/...

    springboot-angular

    2. **起步依赖(Starter POMs)**:预定义的Maven或Gradle依赖集,帮助开发者快速添加需要的功能,如`spring-boot-starter-web`用于Web开发。 3. **内嵌服务器**:Spring Boot可内嵌Tomcat或Jetty服务器,无需额外...

    基于ssm+vue校园二手交易管理系统.zip

    【标题】"基于SSM+Vue的校园二手交易管理系统"是一个综合性的项目,结合了Java后端技术SSM(Spring、SpringMVC、MyBatis)与前端Vue.js框架,旨在为大学生提供一个便捷的在线交易平台,促进校园内部的资源循环利用。...

    spring-mvc开发所有jar包【4.3.4】

    这个版本的Spring MVC为非Maven项目提供了方便,避免了开发者为了集成Spring框架而手动下载和配置各种依赖的麻烦。 1. **spring-context-4.3.4.RELEASE.jar**:这是Spring框架的核心上下文模块,包含了Bean工厂和...

    OctoAsk:C301 项目 - OctoAsk

    另外,可能会使用Maven或Gradle作为项目构建工具,管理依赖关系。 3. **自然语言处理(NLP)**:OctoAsk系统的核心部分是其NLP模块,可能包含了词法分析、句法分析、语义解析等技术,用于理解用户输入的问题。可能...

    Mybatis狂神说教学自记笔记markdown格式

    1. 添加Mybatis依赖:在Maven项目中,需要在pom.xml中引入Mybatis的依赖。 2. 配置Mybatis核心配置文件:mybatis-config.xml,包括数据源、事务管理器、SqlSessionFactory等配置。 3. 创建Mapper接口和Mapper XML...

    基于ssm+vue的学生宿舍设备报修管理系统.zip

    这个系统是为了解决学生宿舍设备报修问题而设计的,它结合了Spring、SpringMVC和MyBatis(SSM)三大Java Web框架,并引入了前端Vue.js库,以提供更高效、友好的用户体验。下面将详细阐述系统的组成部分和相关技术点...

    EasyChatServer是一个简单的聊天IM软件后端程序,采用SpringBoot + Netty框架。提供了单.zip

    EasyChatServer的代码可能组织为Maven或Gradle项目,开发者可以通过导入`EasyChatServer-master`目录下的源码,在IDE如IntelliJ IDEA或Eclipse中进行编译和调试。部署时,可以打包成可执行的JAR文件,然后在服务器上...

Global site tag (gtag.js) - Google Analytics