PicoContainer的setter注入

PicoContainer的setter注入,并不带有可选性,也就是只要有setter而且注册了组件,则无论想与不想,都会注入。

某情况,某类存在AB属性,我只想B属性注入,但AB组件都已注册,而且setter方法必须存在。

是否在这种情况下,则需要扫描annotation技术了?

知道的,求说一些经验和看法,我刚踏入架构的领地-。-(第一次从用器踏上造器)

我把“容器”想象为“环境”,把“业务对象”想象为“人”。

一般情况下,是“人”向“环境”索取“物”,IoC容器是“环境”向“人”赐予“物”。这是IoC控制反转的含义所在。

赐予的方式也称为依赖注入(DI),分为三种,其区别取决于“业务对象”接受“注入”的“位置”的不同,即setter、constructor、interface injection。

setter注入,是在“业务对象”的setter方法参数上注入;constructor注入,是在“业务对象”的constructor方法参数上注入;interface注入则是在“业务对象”的类声明处注入。

constructor注入的优点是,依赖关系随着业务对象的创建而建立,缺点是如果依赖关系复杂,业务对象的创建比较繁琐;setter注入刚好克服了构造注入的缺点,但却失去了构造注入的优点,使用依赖关系之前,必须先setter。选择哪一种注入方式,取决于依赖关系的复杂性,一般说来,简单的依赖关系由constructor注入方便一些,而复杂的依赖关系则有setter注入方便一些。

interface注入一般不采用,此时业务对象必须实现依赖关系注入器的接口,这是容器对业务对象的入侵,即容器具有入侵性。“业务对象”只因为失血过多(没有实例值),需要注入血液(赋予实例值),但“业务对象”并不依赖或关心注入血液的针管,即容器注入实例值的方式。

可以看出,IoC与DI分别从容器与业务对象的角度对同一件事情进行描述。如果是使用xml配置,要用到java.lang.reflection和xml解析的类库,如果是使用注解机制代替xml配置,自然还要用到java.lang.annoation类库。这两个技术点我也在研究,目前先用工厂模式凑合用用。

在Martin Flower著名的文章《Inversion of Control Containers and the Dependency Injection pattern》中,提及了PicoContainer加以采用contructor注入方式,Spring建议采用setter注入,但是IoC/DI框架一般都会同时提供两种注入方式。

最后,个人以为IoC/DI的用处虽然不容小觑,但毕竟只是一个技巧而已,感觉还称不上架构,架构这个词还是用来描述软件的宏观层面较好,不然到时需要时都可能找不到合适的词了。呵呵。

造器方面,IOC/DI是大势所趋,为的就是降低耦合,提高复用,使用IOC/DI后又把责任交合容器了。

IOC的确不算是一种架构,只是一种模式而已,而我也只是选择了这种方向而已。自己写写IOC和AOP,然后从中得到的经验,然后向广大微容器学习更多的额外知识。时机成熟,就可以按自己的设计来架构了。

知识的不断积累和反思,自己经常想到一些新的方式,却因为器没有提供,所以不能做,也不可能要别人为自己做吧-3-。想突破这种感觉,到达可以掌握一切的感觉是最舒服的。

我也没有想到要以世界著名框架为目标,比起那种目标,我更喜欢“无框胜有框”的感觉——随手拈来几个包,小小配置一下,好了-0-。JF感觉就如这样,包大多没有什么特别,但它却制造出DDD的设计空间。我一直提醒自己不要为架构而架构(那是一个大忌)——我一直相信架构是为设计服务的。

感叹一下,踏入造器境地,真的还要花很多力气啊~~~~~

感叹完一下,忘了继续问····

使用PicoContainer情况如下:
A类当中有B类属性和C类属性(都满足setter注入环境)

当ABC类都注册了,现在从容器中获取A实例,但现在我只需注入B类,C类不注入。

其实就是setter本来目的不是为了注入,所以B和C的setter都存在。

而constructor注入实现如下:
class A{
B b;
C c;
A(B b){
this.b = b;
}
}

但setter注入的话,因为一些原因C类的setter必须存在和必须要注册,但我又不想其注入。鉴于这种状况,我是用XML配置方式实现的。是又另外一种方便解决方案,还是这本来就是setter的缺点?要通过XML辅助?

“注入”,说白了就是“赋值”。

当然“注入”有其特定的意义:将“赋值”的过程从“业务对象”的“内部”转移到“外部”。这样可根据外部环境的需要,进行灵活的赋值,一定程度上可适应环境的变化。

三种注入方式,只是表示三个不同的注入位置。至于注入的“值”是怎么来的,与它们并无固定的联系。这个“值”通过XML、元数据注解还是工厂的方式给出,则是另外另一个问题了。

打个比方。

constructor注入就像打疫苗,而且是在“业务对象”出生时打,希望“业务对象”一出生后就百毒不侵—使用这个业务对象时,不再需要考虑或注入各种依赖关系了。但这样做可能有一个极大的副作用,“业
务对象”太难产了,看起来就像一个畸形儿——带着一串长长的构造参数。

setter注入就像病时吃药打针,量身定做,按需分配,没病就不要乱打针吃药,即未使用某个依赖关系时,就不注入相应的实例值。

至于药物是怎么来,则与注入方式(即位置)关系不大。你可以自己订制“配方”(XML配置或Annotation注解),而把“造药”交给容器(另一个对象)来捣鼓,也可以自给自足,通过简单的工厂来做。

根据依赖关系的复杂性,灵活使用两个注入方式(可以结合,也可以单独使用)。一般的对象的创建,不都这样吗?

比喻相当不错o(∩_∩)o 。
嗯,单纯说IOC,当然是这样。但具体到某个容器则不知道他所涉及的范围了,也就是不知道在用setter注入时,会不会存在一些设置(在网上查了很久都没有,暂且没有╮(╯▽╰)╭)。

在网上说constructor注入和setter注入基本只是创建顺序不同而已。从实践却得出这样不一样的感觉,所以想看看到底是还有其他解决方案,还是这本来就是一个constructor注入的优势。看来这种注入不但具有完整性,还绝不“顺手牵羊”——约束性。(网上的很少说不“顺手牵羊”这优势啊,难道这用法很少出现?)

嗯,谢谢jdon007了,继续实践去了~~~
[该贴被SpeedVan于2010-12-23 20:19修改过]