对多实例的处理
spring的ioc,原本是在“实例”层面上的。同样的一个类,我可以通过多个标签,得到多个实例。并且,每个bean中的属性配置都可以不一样,从而使我得到多个不一样的实例。
举个例子。我写过这样一个类:
class A implements AI{
private B b;
private C c;
private D d;
@Override
public void aService(){
b.bService();
c.cService();
d.dService();
}
// accessers
}
配置是这样的
<bean id="a1" class="A">
<property name="b" ref="b1"/>
<property name="c" ref="c1"/>
<property name="d" ref="d1"/>
</bean>
<bean id="a2" class="A">
<property name="b" ref="b2"/>
<property name="c" ref="c2"/>
<property name="d" ref="d2"/>
</bean>
题外话,当时写完这个服务,自己很开心。因为我无意间找到了用组合而不是继承的方式,来实现模板模式的方法。
在这里,spring ioc通过xml中的bean,为同一个类配置出了不同的实例。这就是我所说的,在“实例”层面上的ioc。
但是注解呢?注解把ioc挪到了类的层面上。一个类只能有一套配置、得到一个实例。我找了很久,才找到一个@Bean和@Configuration。也还是麻烦得要死,远不如xml来得方便、明了。
对父属性继承的处理
另外,使用注解方式时,对父类属性的配置也是个麻烦。我需要给子类重写set方法,然后将@Resource标签放在重写的标签上。但是xml呢?用parent属性就很轻松了。
其它
还有一些问题,让spring ioc的注解来背锅是有点冤枉。不过,也有这方面的因素。
注解用多了,会影响程序员对spring ioc的使用和理解。
使用方面,xml配置中有一些“高级”的用法,注解用不了,或者很麻烦。前面说的parent,另外还有abstract都算用不了的;甚至有人不知道scope的用法和含义的。
理解上,我也见过有人一直不明白spring容器和bean、实例之间的关系的。这些人的开发经验都不少,至少是可以独立负责一个服务的开发和维护的。
此外,由于一直都是“一个类只能有一个实例;一个实例中实现所有流程”的思路,形成了“所有流程都在一个类中”的定势。结果,没有接口和实现,没有继承和子类,没有重载和重写。每当有流程变化,有功能变化,都加if-else,加switch。好好的一个系统,迅速的腐烂成泥。
话说回来
不过xml也确实有问题:随着系统变大,xml文件也会越来越多、越来越大。不过,相比这种复杂性,我更讨厌胶柱鼓瑟的ioc注解。
2023-02-18 补充
如今我要回来打自己的脸的:注解可真香