使用列表属性避免Spring bean中的循环依赖项

时间:2014-07-01 14:39:52

标签: java spring dependency-injection circular-dependency

假设我有一个使用Spring框架的Maven项目。 Maven项目本身有三个模块:commoncomponent_acomponent_b。让我们说common定义一个带有属性listeners的事件监听器bean,它是监听事件的所有内容的列表。监听器在component_acomponent_b模块中定义。

总结:

应用上下文-component_a.xml:

<beans>
    <bean id="someListener" class="com.whatever.component_a.SomeListener"/>
    <bean id="anotherListener" class="com.whatever.component_a.AnotherListener"/>
</beans>

应用上下文-component_b.xml:

<beans>
    <bean id="yetAnotherListener" class="com.whatever.component_b.YetAnotherListener"/>
</beans>

应用上下文-common.xml:

<beans>
    <bean id="eventListener" class="com.whatever.common.EventListenerImpl">
        <property name="listeners">
            <list>
                <ref bean="someListener"/>
                <ref bean="anotherListener"/>
                <ref bean="yetAnotherListener"/>
            </list>
        </property>
    </bean>
</beans>

(我想我的格式就在这里......但如果我没有,请原谅我)

我的问题是,现在common依赖于两个component_*模块,而不是相反。我的common模块不再正确构建,因为我的集成测试无法在没有其他模块的情况下正确创建容器。

因此,鉴于我的eventListener需要有一个包含所有侦听器的列表这一事实,使用什么样的好模式可以使我的模块在构建/测试期间保持独立?

我可以想到一些模式:

  1. 在不同版本中使用不同版本的eventListener 上下文
  2. 使用新bean方便注册
  3. 每个内部 setEventListener()打电话,记得打电话 eventListener.addListener(this);
  4. 但我很好奇Spring是否有任何内置的方法可以做得更好......

1 个答案:

答案 0 :(得分:0)

您可以做的是在主模块中自动装配一个监听器列表。然后,每个其他模块可以提供此接口的实现和适当的componentscan / xml声明。

Mainmodule :(伪代码)

@Service
ListenerService {

    @Autowire
    List<ListenerIntf> listeners;

    public handleListeners() {
        foreach listeners {
            listener.onEvent();
        }
    }
}

第1单元:

@Component
@Order // if desired
Listener1 implements ListenerIntf {
    public onEvent();
}