对多实例的处理

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 补充

如今我要回来打自己的脸的:注解可真香