(思考)Spring第一篇之IoC
(觉得自己一直思考太少且深度不够,所以加上这个前缀提醒自己-思维才是核心竞争力。)
spring目前可能用到的有几个模块:ioc、aop和tx,第一篇主要对ioc一些essential的知识做一个总结,不牵扯任何技术细节上的东东,很多都是个人的一些想法,所以不一定准确,欢迎大家指出来,可以一起讨论。附件是我在写文章时候,参考的一篇文献。
一、ioc(inversionofcontrol)
1.什么是ioc?
以往不好的编程体验,过于依赖于implementation,这样的结果是:implementation对整个程序拥有了绝对的control。因为implementation都是硬编码,所以造成的结果是难于扩展,无法满足ocp。ioc就是inversethecontrolofimplementationstotheinterfaces,即面向接口编程。这样无论是上层的business,还是下层的implementation都依赖抽象层(接口或者抽象类),抽象层拥有绝对的control。这样的结果是使整个项目有了更好的extensible。
spring框架的核心是ioc容器,所以它有着很好的nointrusive。
介绍到这,就很想知道ioc在spring中是如何实现的很自然的引出了第二个话题。
2.如何实现ioc?
实现ioc有两种主要的方式,一种是servicelocator(服务定位器),一种是dependecyinjection(依赖注入)。为何要引入这两种方式,举一个简单的例子可以说明这个问题。
class people{ private action action; public people(){ action =new manaction(); }}interface action{}class manaction implement action{}
注意,上例中你虽是面向接口编程,但实际上people类,既依赖于action接口,又依赖于manaction(具体的implementation),而且你在编译期就binding了这种关系。这显然不是我们所期望的那种“纯粹的”面向接口编程。如何达到这个要求,有人提出了“plugin”这个概念,既我们编写的plugin是在运行时才binding到这个系统中的,插入的时间和方式,完全于plugin的编写者无关,如何做到呢?于是就有了最开始所说的的两种实现方式(模式)。
首先说说di,di分为三种:type1,type2和type3。
type1:interfaceinjection,要实现它,需要再定义一个接口叫actioninjection每个使用action的类都必须实现这个接口,然后在配置文件中定义injection属性,把manaction作为value传入进去即可。这种方式由于要在你自己的类(比如people)中实现actioninjection接口,于框架的耦合度较高,所以具有较强的intrusive,不推荐使用。而type2和type3,即是spring所使用的方式。网上有很多关于它们的讨论,我大致总结一下:type3使用构造子注入,优先使用,因为它具有较强的隐蔽性,可以保护你不愿意改变的属性;然而有时候,会有多个构造函数,或者是构造函数的参数很多(记住顺序很麻烦),就应该使用type2setter方法注入。
最后说说servicelocator(sl),我对它的理解应该也不准确,大概说说也算是抛砖引玉吧。di中控制者和被控制者,完全感受不到对方的存在,它们之间的关系是在runtime时才binding的,具有很强的灵活性,然而正是因为这种灵活性若是超过了一定限度,会使你迷失在查找配置文件的海洋中。而sl要求必须在编译器就有一个sl对象知道你application所需的全部服务,而具体这些服务的注册是通过di在runtime时和application所需要的sl对象binding在一起的,所以sl一般会是一个接口,而你的application在runtime中通过sl对象查找服务,然后调用它,这样的好处是,你可以显示的看到你所拥有的全部的服务,和配置文件解耦。
到这里,可以把ioc想象为一个实体东西,它的“体”是control,“相”是inverse,“用”呢?
3.用ioc干什么?
换个角度说,就是用ioc操作什么?答案是beans。操作的过程与spring框架紧密结合在一起,spring框架提供了两个方式一个是beanfactory接口,一个是使用applicationcontext容器,下面这段话解释的很清楚,不再赘述。
<divclass="quote_title">引用