今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

Slim3のServiceの初期化で無限ループしてStackOverFlowErrorが発生した

Slim3で複数のサービスを作ったけど、サービスがそれぞれ相互のデータを必要としていたために、それぞれでサービスのインスタンスを作った。

public class FooService {
    private FooService fooService = new FooService();
    private BarService barService = new BarService();
}

public class BarService {
    private FooService fooService = new FooService();
    private BarService barService = new BarService();
}

見事に無限ループしてStackOverFlowErrorが発生。

at FooService.(FooService.java:??)
at BarService.(BarService.java:??)
at FooService.(FooService.java:??)
at BarService.(BarService.java:??)

引数付きコンストラクタを作って回避。

public class FooService {
    private BarService barService;

    public FooService() {
        this(null);
    }

    public FooService(BarService bs) {
        if (bs == null) bs = new BarService(this);
        barService = bs;
    }
}

public class BarService {
    private FooService fooService;

    public BarService() {
        this(null);
    }

    public BarService(FooService fs) {
        if (fs == null) fs = new FooService(this);
        fooService = fs;
    }
}


04/16追記
やっぱり、双方向から呼び合うのはよろしくないのでリファクタリングした。
BarServiceの中でFooServiceを使わなきゃいけない処理はFooServiceに移動して、BarServiceの中からFooServiceを使わないようにした。

public class FooService {
    private FooService fooService = new FooService();
    private BarService barService = new BarService();
}

public class BarService {
    private BarService barService = new BarService();
}

苦し紛れだった引数付きコンストラクタを削除できて、結果的にすっきり。