2

在我的 MVP 应用程序中,我使用如下代码来连接我的 Presenter 和 View:

View view = new View();
Presenter presenter = new Presenter(view);
view.setPresenter(presenter);

类在临时无效状态下View构造,调用setPresenter纠正。如果在没有配置 Presenter 的情况下使用 View ,我在类中有一些代码View会抛出一个。IllegalStateException

我希望 Spring 可以将这种关系与如下配置联系起来:

<bean id="presenter" class="com.foo.Presenter">
  <constructor-arg ref="view" />
</bean>

<bean id="view" class="com.foo.View">
  <property name="presenter" ref="presenter" />
</bean>

这失败了一个冗长的循环依赖异常。

有没有办法告诉 Spring 构造viewbean,然后presenter在最终调用 setter 之前构造 bean view


一个相关的问题是创建所有 bean 之后的 Spring setter 依赖注入。但是,建议的解决方案之一是通过使用基于设置器的连接来解决循环依赖关系,这正是我在这里没有做的。最新的手册似乎也同意——见题为“循环依赖”的方框:

一种可能的解决方案是编辑某些类的源代码以由设置器而不是构造器配置。或者,避免构造函数注入并仅使用 setter 注入。也就是说,虽然不推荐,但是可以通过setter injection来配置循环依赖

4

2 回答 2

2

我确信有更好的解决方案,但如果一切都失败了,你可以“手动”做:

配置:

<bean id="presenter" class="com.foo.Presenter">
</bean>

<bean id="view" class="com.foo.View" init-method="init">
</bean>

查看类:

public class View implements ApplicationContextAware {

    private ApplicationContext applicationContext;
    private Presenter presenter;

    public void init(){
        presenter = (Presenter)applicationContext.getBean("presenter");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

作为一个额外的说明,如果你有annotation-driven你的配置,你可以做@Autowired private ApplicationContext applicationContext;而不是实现 ApplicationContextAware 接口。

于 2013-03-15T08:49:14.997 回答
1

一些进一步的研究发现了一个解决方案。最初,我尝试颠倒 XML 配置文件中 bean 定义的顺序,它起作用了:

<bean id="view" class="com.foo.View">
  <property name="presenter" ref="presenter" />
</bean>

<bean id="presenter" class="com.foo.Presenter">
  <constructor-arg ref="view" />
</bean>

但是,这感觉不对,因为我相信我不应该依赖文件排序来确保事情不会中断。这导致意识到depends-on可以解决问题:

<bean id="presenter" class="com.foo.Presenter" depends-on="view">
  <constructor-arg ref="view" />
</bean>

<bean id="view" class="com.foo.View">
  <property name="presenter" ref="presenter" />
</bean>

我欢迎评论这是否是一个好方法。很有可能我以一种非故意的方式使 Spring 屈服于我的意愿。

于 2013-03-15T09:32:25.570 回答