文档章节

模块依赖管理

哈库纳
 哈库纳
发布于 2013/09/16 20:27
字数 1333
阅读 3034
收藏 69

这篇是承接《轻量级 Java 开发框架 设计》系列Blog文的后续文章。

    如果你对 OSGi 有所了解,应该会记得在 OSGi 框架中模块是一个独立的插件项目。作为插件项目而言可以通过引用其他插件来完成第三方库依赖。其实这一思想其实和我们引入其他 Jar 包到自己 ClassPath 目录中道理是一样的。

    不过不同的是 OSGi 它会单独为每一个插件提供一个独立的 ClassLoader 。然后依赖它的插件会自动从它的 ClassLoader 中装载所需的程序资源。这样一来 OSGi 容器就会知晓每一个插件工程的依赖项。当 OSGi 容器启动时就可以进行模块依赖检查并提示开发者缺少哪些部件。同时也可以为容器根据要求有选择的加载启动。

    其实在轻量化软件开发中我们并不需要这么复杂的处理逻辑。通常情况下软件产品一旦被分为多个模块之后,我们就会为不同的模块构建一个它们独立的 Java 工程。但是这样会遇到一些列问题:
    1.首先模块并不知道自己的入口程序是什么?
    2.其次当A模块依赖B模块时,没有一个明显的启动顺序。
    3.模块之间需要一个环境进行彼此协调。

    因此,大部分项目会为自己构建一个基本开发环境用来解决这些问题。同时也会通过开发环境提供软件开发所必要的一系列工具类。为了解决上面这些问题在设计模块时引入模块 生命周期 或者称之为运行阶段:

    1.init  :初始化阶段,该阶段的目的是为了在正式启动之前给予模块一些准备工作,其中包括了明确依赖。
    2.start:启动阶段,这一阶段可以用来注册Servlet/Filter/发布Service服务等。
    3.stop:停止阶段,这一阶段可以用来反向启动阶段所做的事情比方解除注册Servlet/Filter等。

下面给出一个例子:

@AnnoModule()
public class Mode1 implements Module {
    public void init(ApiBinder apiBinder) {
        DependencySettings dep = apiBinder.dependency();
        /*弱依赖,目标模块即使没有成功启动也不影响当前模块*/
        dep.weak(Mode2.class);
        /*强依赖,当前模块的启动必须依靠目标模块*/
        dep.forced(Mode3.class);
        // }
    public void start(AppContext appContext) {
        //
        appContext.registerServices(....);//该方法目前并不存在,演示用意
        appContext.registerServices(....);
    }
    public void stop(AppContext appContext) {
        //
        appContext.unRegisterServices(....);//该方法目前并不存在,演示用意
        appContext.unRegisterServices(....);
    }
}
@AnnoModule()
public class Mode2 implements Module {
    public void init(ApiBinder apiBinder) {
        apiBinder.dependency().weak(Mode3.class);
        System.out.println("Mode2 init!");
    }
    public void start(AppContext appContext) {}
    public void stop(AppContext appContext) {}
}
@AnnoModule()
public class Mode3 implements Module {
    public void init(ApiBinder apiBinder) {
        throw new RuntimeException();
        //这里抛出异常的用意是模拟 模块3 初始化失败 用来演示 模块1 因为强制依赖而受到牵连不会启动。
    }
    public void start(AppContext appContext) {}
    public void stop(AppContext appContext) {}
}

这个例子中依赖顺序是:Mode1>Mode2>Mode3。所以启动顺序应该是 3,2,1。下面是启动信息节选: 


这样的设计我觉得具有下面几个优点:
    1.明确了模块启动各个部分要作的事情,可以使代码逻辑更加清晰易懂。
    2.保护加载失败的模块不会造成更大的牵连。
    3.数据据服务、用户登陆认证;这样的模块之间可以明确依赖关系,并且通过日志的形式直观的展现出来。
    4.将来可以为实现单独停止某一个模块做技术铺垫。
    5.为热部署做技术铺垫。

不知道大家对这样的技术方案有何看法,欢迎一起讨论。

补充一下内容:
    在这个框架的设计目的是为了快速构建开发环境。因此从任何角度来说和OSGi都有很大的区别。之所用OSGi做比较是由于,Module 的管理方式和OSGi的插件依赖体系很像。但是它们两者其本质是不同的两个东西。

    比方说现在构建一个Web开发环境,需要如下功能:Action服务、ORM服务、数据源服务、业务Bean。根据不同的产品或项目还需要:任务模块、远程同步、消息服务,等等。

    这个架构中可以很显然的看到:Action调用在调用具体Action类的时候,业务Bean一定是预先可到达的。所以业务Bean服务的启动应当在Action之前。而ORM服务恰恰需要数据源服务的支持,这也是一个依赖的关系。

    在设计 Hasor 的时候我考虑的是提供一个开发框架,可以用最简单的方式将上面列出的各种模块服务串联成一整个架构体系。而非设计了一个与OSGi同样目标的轮子。

----------------------------------------------------------------
目前的开发代码存放于(包括Demo程序)
    Github:    https://github.com/zycgit/hasor
    git@OSC: http://git.oschina.net/zycgit/hasor

非常感谢您百忙之中抽出时间来看这一系博文。可以通过Maven 中央仓库网站  http://search.maven.org/ 搜索 Hasor 下载 hasor 的相关代码。

© 著作权归作者所有

哈库纳

哈库纳

粉丝 961
博文 84
码字总数 151810
作品 4
杭州
后端工程师
私信 提问
加载中

评论(10)

哈库纳
哈库纳

引用来自“西夏一品堂”的评论

楼上的对OSGI一致差评。
那么请问,最后,大家还在使用OSGI吗?
看应用场景去选,没有唯一的答案,或许在这里用不了,但是换个地方就非常适合。
西夏一品堂
西夏一品堂
楼上的对OSGI一致差评。
那么请问,最后,大家还在使用OSGI吗?
悠悠然然
悠悠然然

引用来自“哈库纳”的评论

引用来自“hantsy”的评论

凡是用上 OSGI,就不提什么轻量级了。

Spring 都放弃了 OSGI 了, 3.0.5 后的 Jar不再包含 OSGI 信息了。

Spring 开始另外一个子项目, Spring Plugin, Spring 自己模块系统。

Spring Plugin 体系值得参考借鉴,OSGi确实是太笨重。 前几日还在想让 Hasor 支持热部署,经过这几天大家讨论。我觉得如果踏上这条路就真的陷入泥潭了。

其实打造它的目的就是提供一个简化的 模块依赖体系,然后提供一个较为完备的基础功能。从而用作开发环境搭建的基础。

确实,一开始我也构建一个插件体系,后来放弃之。
实际上只要基于soa就已经松耦合了。
所以我保留soa,不再使用插件体系
哈库纳
哈库纳

引用来自“hantsy”的评论

凡是用上 OSGI,就不提什么轻量级了。

Spring 都放弃了 OSGI 了, 3.0.5 后的 Jar不再包含 OSGI 信息了。

Spring 开始另外一个子项目, Spring Plugin, Spring 自己模块系统。

Spring Plugin 体系值得参考借鉴,OSGi确实是太笨重。 前几日还在想让 Hasor 支持热部署,经过这几天大家讨论。我觉得如果踏上这条路就真的陷入泥潭了。

其实打造它的目的就是提供一个简化的 模块依赖体系,然后提供一个较为完备的基础功能。从而用作开发环境搭建的基础。
hantsy
hantsy
凡是用上 OSGI,就不提什么轻量级了。

Spring 都放弃了 OSGI 了, 3.0.5 后的 Jar不再包含 OSGI 信息了。

Spring 开始另外一个子项目, Spring Plugin, Spring 自己模块系统。
哈库纳
哈库纳

引用来自“东胜神洲”的评论

OSGI 之所以重,在于这是一个工业级产品,从汽车。。到企业应用都 囊括在内。。能做得轻?。。做个接口,然后再来个简单消息队列。。基本就可以达到模块化的 5 ~ 6 成 “效果”。。想百分百,不如干脆玩 OSGi...

做个接口来个消息队列 也需要搭建一个简易的环境将 消息系统和整个架构 联系到一起。设计这个东西的目的就是降低 设计的新组件和已有开发环境的融合问题。

一般来说设计的新组件在系统中直接 new 或者 注入进来就可以使用。但是这个组建的初始化顺序不能是随机的。轻量级模块化,要作的就是只管好模块依赖。提供一个环境让模块自由的注册和注销组件 就可以了。

其实这一点和Spring的Context容器倒是有点相似,不过Spring没有提供模块依赖关系这样的功能。
东胜神洲
东胜神洲
OSGI 之所以重,在于这是一个工业级产品,从汽车。。到企业应用都 囊括在内。。能做得轻?。。做个接口,然后再来个简单消息队列。。基本就可以达到模块化的 5 ~ 6 成 “效果”。。想百分百,不如干脆玩 OSGi...
哈库纳
哈库纳

引用来自“yangzhiyong”的评论

引用来自“缪斯的情人”的评论

但凡扯上osgi,就没有轻量级可言,越陷越深

这个目前在企业级里赞同。。

我觉得 OSGi 是一个 模块化的服务平台。如果在企业级上应用服务平台,我觉得确实没有什么轻量级可言。这滩泥的确很深。

不过需要澄清的是,在这个框架的设计目的是为了快速构建开发环境。因此从任何角度来说和OSGi都有很大的区别。之所用OSGi做比较是由于,Module 的管理方式在某种程度上和OSGi的插件依赖体系很像。
dreamers
dreamers

引用来自“缪斯的情人”的评论

但凡扯上osgi,就没有轻量级可言,越陷越深

这个目前在企业级里赞同。。
缪斯的情人
缪斯的情人
但凡扯上osgi,就没有轻量级可言,越陷越深
Maven 中 dependencies 与 dependencyManagement 的区别

Maven 中 dependencies 与 dependencyManagement 的区别 前提 这段时间项目中遇到过了一些 Jar 包冲突的问题,很多是由于我们项目模块很多的时候,用 Maven 管理不当导致的冲突问题,本文就这...

晨猫
2018/10/31
0
0
Gradle学习(二十四)——依赖管理简介

什么是依赖管理 软件很少独立工作。在大多数情况下,项目都要依赖于lib形式的可重用功能,还有就是项目可能被切分成多个单独的模块来构成模块化系统。依赖管理是一种可以让项目可以自动化得定...

lastsweetop
2018/03/30
0
0
Gradle学习(二十五)——依赖管理术语

依赖管理有大量的术语,为了方便理解整个依赖管理的过程,我们先要理解一下相关的术语 配置 配置是一组实现特殊目的的依赖项集合:比如配置表示编译项目的一组依赖集合。配置可以访问底层的已...

lastsweetop
2018/04/08
0
0
1.osframe后台开源框架架构概述

开源项目名称: osframe管理系统 托管地址: http://git.oschina.net/haizicq/osframe 主要技术: spring mvc、spring、hibernate、angular js、seajs、bootstrap、shiro 框架介绍: 本框架是...

王春-海子
2016/06/27
203
0
Maven依赖中scope的含义

Maven依赖中scope的含义 整理一下Maven中Scope的详细作用,都是抄的别人内容整理了一下。参考: https://blog.csdn.net/claram/article/details/77646263 https://blog.csdn.net/kimylrong/...

UEUEO
2018/11/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

基础工具类

package com.atguigu.util;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;import com.alibaba.druid......

architect刘源源
今天
43
0
P30 Pro劲敌!DxO官宣新机:排行榜又要变

5月26日晚间,DxOMark官方推特预告,将在5月27日公布一款新机型的DxOMark评分,猜猜是哪款? 网友猜想的机型有:红米K20、谷歌Pixel 3a、索尼Xperia 1、诺基亚9 PureView等。 DxOMark即将公布...

linux-tao
昨天
15
0
Ubuntu18.04.2窗口过小不能自适应(二次转载)

解决Ubuntu在虚拟机窗口不能自适应 2018年09月06日 16:20:08 起不了名儿 阅读数 855 此博文转载:https://blog.csdn.net/nuddlle/article/details/77994080(原地址) 试了很多办法这个好用 ...

tahiti_aa
昨天
2
0
死磕 java同步系列之CountDownLatch源码解析

问题 (1)CountDownLatch是什么? (2)CountDownLatch具有哪些特性? (3)CountDownLatch通常运用在什么场景中? (4)CountDownLatch的初始次数是否可以调整? 简介 CountDownLatch,可以...

彤哥读源码
昨天
6
0
Nginx提供下载apk服务

有时候我们可能需要提供文件或者其他apk下载链接,通过 nginx 配置可以很简单地实现。 server {    listen 80;    server_name download.xxx.com;    root app;    locati...

Jack088
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部