Java服务提供框架

本文探讨Effective Java E3 CH2中提到的服务提供框架,引申点有JDBC实现、SPI机制等。

原文

There are three essential components in a service provider framework: a service interface, which represents an implementation; a provider registration API, which providers use to register implementations; and a service access API, which clients use to obtain instances of the service. The service access API may allow clients to specify criteria for choosing an implementation. In the absence of such criteria, the API returns an instance of a default implementation, or allows the client to cycle through all available implementations. The service access API is the flexible static factory that forms the basis of the service provider framework.
An optional fourth component of a service provider framework is a service provider interface, which describes a factory object that produce instances of the service interface. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65). In the case of JDBC, Connection plays the part of the service interface, DriverManager.registerDriver is the provider registration API, DriverManager.getConnection is the service access API, and Driver is the service provider interface.

解释及思考

服务提供框架的三个必要组成部分: 服务接口(Service Interface)、服务提供者注册API( Provider Registration API)、服务获取API(Service Access API)
客户端通过调用Service Interface实现功能调用,服务获取API帮助客户端获取服务接口实例,服务获取API通常为静态方法,客户端可以自由选择不同的服务实现。
Provider Registration API注册Service Implementation(什么是注册)
还有一个可选择的组成部分:服务提供接口(Service Provider Interface,SPI)
在日常使用中,SPI提及频率也很高,在没有SPI的情况下,service implementation必须通过反射的方式实例化(why)。

回顾JDBC的使用方法:

   static{
         try {
             //1.加载驱动程序
             Class.forName("com.mysql.jdbc.Driver");
             //2.获得数据库的连接
             conn = DriverManager.getConnection(URL, NAME, PASSWORD);
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }

客户端程序通过Connection对象操作数据库,则Connection相当于service API, DriverManager.getConnection相当于Service Access API. Class.forName("com.mysql.jdbc.Driver") 这个步骤相当于Provider注册,加载mysql驱动之后provider提供的connection实现才是客户端所需的实例; Class.forName("com.mysql.jdbc.Driver")是将Driver类加载到内存中,加载至内存中以后Driver会调用DriverMananger的rigisteDriver方法。
考虑JDBC的实例,总结service interface, provider registration API, Service Access API三者之间的关系和简单叙述为:

  • provider registation API: 调用者告诉提供者,provider做一些服务准备工作(多为provider的必要类加载)。
  • service interface: 调用者直接调用用以获取提供者提供的功能
  • service access API: Service Interface有不同的实现,调用者通过service access API获取所需的interface实例。
    三者关系如图所示:


    服务提供框架结构图

现在可以继续思考一个问题,在缺席SPI的情况下,provider是如何注册的?原文中有一段说:

An optional fourth component of a service provider framework is a service provider interface, which describes a factory object that produce instances of the service interface. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65)

原文中说,在没有SPI的情况下,provider只能通过反射的方式实例化service interface, Service Interface实现为新的实例,在运行过程中初始化新的实例只能通过反射的方法。在JDBC API实现中,注册过程使用反射获取新的Diver实例,service interface通过调用Driver实例获取。
SPI是什么,SPI又是如何通过接口的方法避免使用反射的?SPI不与使用反射方法冲突,Java Service Loader中同样应用了反射。原文定义SPI为提供service interface实例的静态工厂。
目前对SPI的理解为:提供caller调用provider的接口,用于provider注册。

扩展

上述模式称之为service provider framework pattern(服务提供者模式),服务提供者模式的变体如
桥接模式,依赖注入框架可以视为service provider。

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容