简体   繁体   English

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

[英]Avoiding circular dependencies in Spring beans with list properties

Let's say that I have a Maven project using the Spring framework. 假设我有一个使用Spring框架的Maven项目。 The Maven project itself has three modules: common , component_a , and component_b . Maven项目本身具有三个模块: commoncomponent_acomponent_b And let's say that common defines an event listener bean with a property listeners , which is a list of everything listening for events. 假设common定义了一个带有属性listeners的事件侦听器bean,该侦听器bean是所有侦听事件的列表。 Listeners are defined in the component_a and component_b modules. 侦听器在component_acomponent_b模块中定义。

To summarize: 总结一下:

applicationcontext-component_a.xml: applicationcontext-component_a.xml:

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

applicationcontext-component_b.xml: applicationcontext-component_b.xml:

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

applicationcontext-common.xml: applicationcontext-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>

(I think I got the format right here...but forgive me if I didn't) (我想我的格式就在这里...但是如果我不原谅我)

My problem is that now common has a dependency on both of the component_* modules, instead of the other way around. 我的问题是,现在common依赖于两个component_*模块,而不是相反的方式。 My common module no longer builds properly, because my integration tests cannot properly create the container without those other modules. 我的common模块不再正确构建,因为如果没有其他模块,我的集成测试将无法正确创建容器。

So given the fact that my eventListener needs to have a list of all of its listeners, what's a good pattern to use that will keep my modules independent during building/testing? 因此,考虑到我的eventListener需要具有所有侦听器的列表这一事实,有什么好用的模式可以使我的模块在构建/测试期间保持独立?

I can think of a few patterns: 我可以想到一些模式:

  1. Using different versions of eventListener within different contexts 在不同的上下文中使用不同版本的eventListener
  2. Using a new bean to facilitate the registration 使用新bean简化注册
  3. Inside each setEventListener() call, remember to call eventListener.addListener(this); 在每个setEventListener()调用中,请记住调用eventListener.addListener(this);

But I'm curious if Spring has any built-in way of doing this better... 但是我很好奇Spring是否有任何内置方法可以更好地做到这一点...

What you could do instead is autowiring a list of listeners in your main module. 您可以做的是在主模块中自动装配侦听器列表。 Each other module can then just provide implementations of this interface and a proper componentscan/xml declaration. 然后,每个其他模块都可以仅提供此接口的实现以及适当的componentscan / xml声明。

Mainmodule: (pseudocode) 主模块:(伪代码)

@Service
ListenerService {

    @Autowire
    List<ListenerIntf> listeners;

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

Module 1: 模块1:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM