Spring向父类属性注入问题

技术 2016-09-07

众所周知,Spring最大的特点就是IOC容器以及它的依赖注入机制,它将原本主动调用的模式,改为“被动”调用,大大减轻了类之间的耦合度。

最近在开发项目的时候,遇到了一个小问题,项目是采用比较老式的配置文件注册方式,原来学spring的时候,都是用注解,所以很明确可以解决父类注入问题,但是配置文件一下就有点头大了。

一开始是配置成了这样:

<bean id="adjustSourceDAO" class="heb.bf.dao.Adjust.imp.AdjustSourceDAOImpl">
    <property name="dataSource" ref="dataSource"/>
</bean> 

<bean id="sourceBOBase" class="heb.bf.bo.Base.BFSourceBOBase">
     <property name="adjustSourceDAO" ref="adjustSourceDAO"/>   
</bean>     

<bean id="adjustSourceBO" class="heb.bf.bo.Adjust.imp.AdjustSourceBOImpl" parent="sourceBOBase">
    <property name="adjustSourceDAO" ref="adjustSourceDAO"/>   
    <property name="budgetDAO" ref="budgetDAO"/>
</bean> 

我自己觉得一点问题都没有啊,很明确的子类父类关系,用到了parent属性,但是启动之后,跟踪到sourceBOBase中,sourceBOBase自己的adjustSourceDAO属性始终是null的状态。

后来经常查看spring的官方文档中关于bean的注入机制部分,发现它的机制是子类的属性会覆盖父类属性的bean,所以在子类adjustSourceBO中,不应该声明和注册adjustSourceDAO,于是,我将程序调整成以下内容:

<bean id="adjustSourceDAO" class="heb.bf.dao.Adjust.imp.AdjustSourceDAOImpl">
    <property name="dataSource" ref="dataSource"/>
</bean> 

<bean id="sourceBOBase" class="heb.bf.bo.Base.BFSourceBOBase">
     <property name="adjustSourceDAO" ref="adjustSourceDAO"/>   
</bean>     

<bean id="adjustSourceBO" class="heb.bf.bo.Adjust.imp.AdjustSourceBOImpl" parent="sourceBOBase">
    <!-- <property name="adjustSourceDAO" ref="adjustSourceDAO"/>  -->
    <property name="budgetDAO" ref="budgetDAO"/>
</bean> 

注释掉了子类adjustSourceDAO和子类中的adjustSourceDAO属性。再次启动,果然,跟踪到父类的时候,adjustSourceDAO属性赋上了值,而且因为adjustSourceDAO的SETTER/GETTER方法都是public修饰的,所以也可以正常被子类访问。

问题解决!

总结:spring的依赖注入中,如果子类和父类都声明和注册了同一属性,则子类会覆盖父类中的属性,所以,如果业务需要子类和父类去调用同一个类,请删除子类中的属性声明和注册注入。

插曲:在调试过程中,我依靠面向对象的特性,想出了一个特殊的方法来解决这个问题,当然,这属于偏方,不能用在正式的项目上,但是用来开拓思路还是不错的!首先,我在父类中声明属性,并用protected修饰符修饰,然后把SETTER/GETTER方法写在子类中,然后在子类的bean中注册这个注入依赖,OK,依然可以达到相同的效果。

楼主残忍的关闭了评论