`
bruce008
  • 浏览: 170197 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Maven 在项目中的依赖管理

阅读更多

现在基于Java的企业开发如果不是太土或者太前卫基本上都会基于maven 来对项目进行版本管理。 其实用maven 来进行版本管理跟源代码管理和项目的开发流程相关发布,issue管理都有非常紧密的关系。

 

其实目前的项目层次划分还是比较清晰的。 基本上分为三层: 最底层的框架层,应用层 和最上面的use case层。

    1, 框架层提供的是一个基本的框架。由于现在这个系统是要运行在特有的cloud 环境,最悲催的是不能用Spring,所以这个framework层做了很多Spring 干的事情,IOC, 生命周期的组件, 事务管理。 封装了最核心的基于jms消息机制的proactor 模式。另外框架层还定义了很多常用的模块来封装了基础的功能。

    2, 应用层当然是基于框架层定义了系统特有的流程,规则匹配机制,工作引擎。 它也是分为N个不同的模块。

 

    3,  Use case 层则基于应用层根据业务的不同划分成不同的use case。

 

这样看下来, 最起码可以给framework, application 和use case 分别定义一个顶层的pom parent, 然后每一个子模块定义自己的pom。 那怎么来定义pom 里面的版本呢, 一种是顶层的pom 有自己的版本,子模块有自己的版本号。这种管理方法支持不同模块有不同的版本,可以单独release。另外一种是在每一个相同的层次上只有一个版本, 比如整个framework 层只有一个版本号。 划分成不同的模块只是功能方面的划分, 不需要单独release 管理。所以我们还是选择一层一个版本吧。

 

让我们回头看看Maven 解析dependency的rule是:

1,   nearest definition。 如果一个库在依赖树上不同版本被依赖, 在最靠近当前pom 的层次上那个版本获胜。 如果两个都处于相同的层次, 那么谁先定义谁获胜。  这样dependency 出现的先后也很重要了。 

 

2,  如果我们想自己来解决这种多重依赖的问题, 我们可以在自己的pom 来显示定义下这个库的依赖。 这个定义当然就满足它的nearest definition的要求了,  就按我们自己的pom中的版本来了。 

 

3,  我们还可以用exclusive 来排除某个依赖库的依赖。   

 

4,  optional  的依赖 是不会传递的。  

 

 

再看看怎么来定义我们的各个层中pom 的依赖呢:

1, 在各层的pom parent 中 指定dependencyManagement 元素 这层中公共的依赖都放在这里, 常用的依赖的版本在properties 来指定。  子模块中就指定dependency 就可以了。不用知道版本。

 

2,  针对那种依赖不想传递下去, 我们需要加optional 不再传递下去。  比如在我们的framework 层封装了 ibmmq, oracleaq 不同的message queue 实现 那么在application 或者 use case 层 我们不需要同时使用这两种不同的实现, 我们就把ibmmq , oracleaq 的jar  指定成 optional。 这样client 具体使用时再来显式指定。

 

3,  application 可依赖framework, 所以它的有些dependency 是framework 传递下来的, 我们就不再application parent pom 中 指定了。 同样原则也用于 use case 的parent pom。

 

4,  framework, application 跟 use case 三层分别属于不同的svn repository, 它们有不同的版本。 不同的版本发布周期。  基本上是framework 最稳定, application 次之。use case 变化反映了业务,变化最频繁。 

 

 

由于公司,项目性质决定了这个地方是没有任何代码的, 只有些原则方面的东西出现在这个地方了。  

 

 

 

 

 

 

分享到:
评论
1 楼 bruce008 2012-11-13  
其实这个optional 为true 的时候还有个很管用的用法。 比如我们在打war 包的时候, 如果很多jar 包都依赖log4j , 基于这样依赖传递我们用exclusion 在每一个jar 上面排除太麻烦了。  只需要定义一个对log4j 的dependency, optional 为true。 这个时候log4j 的依赖链是最短的,因为我们就是直接依赖。 但同时optional 为true 就不会将log4j 打进来了。  这种用法还是蛮管用的, 呵呵。


另外 <version> </version> 元素可以用parent 中定义的 property。 我们采用这种来做 continous release 还是很爽的。 唯一的要求是对Jenkins server 硬盘容量的限制。 

相关推荐

Global site tag (gtag.js) - Google Analytics