Spring 揭秘之掌管大局的IoC Service Provider

《Spring 揭秘》读书心得之第三章 掌管大局的IoC Service Provider

上篇文章IoC的基本概念里,我们提到了“GM”这一角色,即“Good Man”,当然,最后我们也揭示了他神秘的面纱:IoC Service Provider。第三章的主要内容就是IoC Service Provider的工作内容以及工作方式。需要注意的是:这里涉及的是通用的IoC Service Provider概念,非特指Spring IoC Service Provider。**这种介绍方式,实际上遵循了“从一般到特殊”这样的逻辑过程,便于理解。**提前剧透一下,对于AOP的介绍,也是按照这样的思路进行的哦。

IoC Service Provider的职责

IoC Service Provider的职责有两个:

  1. 创建业务对象;
  2. 解决业务对象之间的依赖绑定;

在使用了IoC之后,我们不再关心业务对象的构建,这一部分工作交由IoC Service Provider处理;IoC Service Provider需要将对象的构建逻辑从客户端对象那里剥离出来,以免这部分逻辑污染业务对象的实现。

仅仅创建一个对象,是远远不能满足需求的:我们需要的是一个可用的,或者说可工作的对象。这意味着,我们从IoC Service Provider那里获得对象必须是功能完善的,即该对象拥有它正常工作所需要的一切,可是它需要什么呢?它需要它所依赖的对象啊! 这就是IoC Service Provider的第二个职责:解决业务对象之间的依赖绑定。

IoC Service Provider通过结合之前构建和管理的所有业务对象,以及各个业务对象间可以识别的依赖关系将这些对象所依赖的对象注入绑定,从而保证每个业务对象在使用的时候,可以处于就绪状态。

在上面这段引用中,有几个关键点需要注意:

  1. IoC Service Provider 创建并管理了系统中的业务对象;
  2. IoC Service Provider 需要各个业务对象之间可识别的依赖关系;
  3. IoC Service Provider 将这些依赖关系转换为了对象的注入绑定;

所以,IoC Service Provider的工作内容也就呼之而出了,可不就是上面的几个关键点嘛。

关于IoC Service Provider的工作内容,即创建、管理-识别依赖-依赖注入,这几个内容,我们需要多问几个“怎么样”,即:怎样创建并管理对象?怎样识别依赖?怎样实现依赖注入?如此,逻辑便更加清晰,结构更加完善,学习效果自然就更好啦。

IoC Service Provider的工作方式

关于如何实现依赖注入这一问题,我们在IoC的基本概念这篇文章里,提到有三种方式来实现DI,实际上这三种方式就是IoC Service Provider将对象间依赖关系转换为了对象注入绑定的方式:接口注入、构造函数注入和Getter/Setter注入。

关于创建并管理这一问题,相对比较简单。在创建方面,需要注意的是,容器如何知道所要创建的对象有哪些;在管理方面主要是IoC Service Provider需要向客户端代码提供获取以及基本属性判断的接口,以便客户端“按需索取”。

我们需要关注的是,IoC Service Provider如何识别各个对象间的依赖关系。IoC Service Provider要识别依赖关系,首先就得有依赖关系吧,没错,我们得先描述依赖关系,然后IoC Service Provider 才能识别啊。换言之,我们描述依赖关系的方法决定了IoC Service Provider识别依赖的方式。

以下是常见的依赖描述方式:

  1. 通过最基本的文本文件;
  2. 通过描述性较强的XML文件;
  3. 通过编写代码;

有了描述依赖的方法,这些IoC Service 便可以为我们服务了。接下来看看具体的描述依赖的方法吧。

直接编写代码

通过为相应的类指定对应的具体实例,可以告知IoC容器,当我们要这种类型的对象实例时,请将容器中注册的、对应的那个具体实例返回给我们;

所谓直接编写代码,就是说我们通过IoC Service Provider提供的接口,使用代码来实现类别-实例之间的对应关系。IoC Service Provider在获得了这种对应关系之后,我们就可以通过类型来获取具体的实例对象了。

看似这种方法只是解决了IoC Service Provider关于对象创建和管理的问题,并没有获得明确的依赖关系。实际上,IoC Service Provider 是获得了依赖关系的。所谓依赖关系,其根源还是代码,也就是类的组成结构,我们没有通过其他的方式来明确描述对象间的依赖关系,但是我们将完整的类及其实例交给了IoC Service Provider啊,它还需要其他描述吗?当然不需要了。比如类A中有一个类B的引用,那么容器在接管A的时候,就会发现它需要一个B,然后容器就通过类B来获得一个对应的实例,并将其交给A。即通过A的Setter方法实现DI。一切尽在不言中,不是吗?

换言之,依赖关系看似是类与类之间的,实际上是对象-对象之间的。而IoC Service Provider通过建立类-对象之间的对应关系,来实现对象-对象之间的依赖关系转换。

通过程序编码让最终的IoC Service Provider(也就是各个IoC框架或者容器实现)得以知晓服务的“奥义”,应该是管理依赖绑定关系的最基本方式

实际上,这种方式也存在问题,不是吗?如果容器中有两个类B的子类,它们都是B,此时容器又该怎么选择呢?所以这种“不加描述”的依赖描述方法,有其优点,也有其缺点。如果我们需要更加精细的依赖关系,自然要选择更加复杂的依赖描述方法了。当然,我们也可以让A直接点出其所需要的B的准确类型,而不是一个模糊的概念。问题嘛,总是,额一般总是有解决办法的嘛。

配置文件方式

这是一种较为普遍的依赖注入关系管理方式。普通文本文件、 properties文件、 XML文件等,都可以成为管理依赖注入关系的载体。最为常见的,还是通过XML文件来管理对象注册和对象间依赖关系。通过XML等配置文件,我们就可以更加精细地描述依赖关系咯,比如A需要的是擅长唱的B,而不是擅长跳的B!。

元数据方式

我们可以直接在类中使用元数据信息来标注各个对象之间的依赖关系,然后由IoC Service Provider根据这些元数据所提供的信息将这些对象组装后,交给客户端对象使用。Java中的元数据就是注解啦。
当然,注解最终也要通过代码处理来确定最终的注入关系,从这点儿来说,注解方式可以算作编码方式的一种特殊情况,不过就更加精细化了。

小结

关于IoC的工作内容以及如何工作,基本上就是这些内容了。值得借鉴的是IoC Service Provider获取依赖关系的方式:可以分为“内”,“外”两个层面:内,就是说通过解析类的结构,以获得其所依赖的类的信息;外,就是指通过额外的配置信息来记录依赖信息。而“外”,也分内外,这是从配置信息所在位置这一角度来区分的:是类外文件还是类内元数据。

内外,是形式上的对立,是效果上的统一。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值