2

私のMVPアプリケーションでは、次のようなコードを使用して、プレゼンターとビューを配線しています。

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

クラスはView一時的に無効な状態で構築され、呼び出しによってsetPresenter修正されます。プレゼンターを構成せずにビューを使用した場合に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最後にセッターを呼び出す前にBeanを作成するように指示する方法はありviewますか?


関連する質問は、すべてのBeanが作成された後のSpringsetter依存性注入です。ただし、推奨される解決策の1つは、セッターベースの配線を使用して循環依存関係を解決することです。これは、私がここで失敗していることです。最新のマニュアルも同意しているようです-「循環依存」というタイトルのボックスを参照してください。

考えられる解決策の1つは、コンストラクターではなくセッターによって構成されるいくつかのクラスのソースコードを編集することです。または、コンストラクターインジェクションを避け、セッターインジェクションのみを使用します。つまり、推奨されていませんが、setterインジェクションを使用して循環依存関係を構成できます

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 に答える