ひこぽんのーと

覚書と雑記です。

JavaEE 7をやってみよう。 CDI その4

その3のつづき。

限定子を使いまわせないか、ということで、
今度は重巡クラスを追加する。

package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.AHeavyCruiser;
import warship.qualifier.First;

@RequestScoped
@First
public class Furutaka extends AHeavyCruiser {

    @Override
    public String getName() {
        return "古鷹";
    }

}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.AHeavyCruiser;
import warship.qualifier.Second;

@RequestScoped
@Second
public class Kako extends AHeavyCruiser {

    @Override
    public String getName() {
        return "加古";
    }
    
}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.AHeavyCruiser;
import warship.qualifier.Third;

@RequestScoped
@Third
public class Aoba extends AHeavyCruiser {

    @Override
    public String getName() {
        return "青葉";
    }

}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.AHeavyCruiser;
import warship.qualifier.Forth;

@RequestScoped
@Forth
public class Kinugasa extends AHeavyCruiser {

    @Override
    public String getName() {
        return "衣笠";
    }

}


これだと、クラス自身のビルドは通るが、
Managed Beanの方が通らない。

package warship;

〜〜 import 省略 〜〜

@Named(value="fleet")
@RequestScoped
public class Fleet {
    @Inject
    @First
    private IWarShip firstShip;

〜〜 以下、省略 〜〜
}

IWarShipの実装としては、First限定子を持つクラスが2つになるため、
インジェクション対象が特定できないから。
そこで、対象を特定する策としてManaged Beanの方を変えてあげると通るようになる。

package warship;

〜〜 import 省略 〜〜

@Named(value="fleet")
@RequestScoped
public class Fleet {
    @Inject
    @First
    private AHeavyCruiser firstShip;

〜〜 以下、省略 〜〜
}

この場合、First限定子を持つAHeavyCruiserの実装は1つだけのため、実行が可能となる。
IWarShipを用いた時よりはクラスの依存度が高まるのが難点だが、
限定子は使いまわすことができる。
実際の業務では、よほど明確で共通的に意味の通る限定子名にしないと、紛らわしいだけかもしれない。

次回、Managed BeanのメンバをIWarShipとしたまま、
任意にインジェクション対象を決定する方法を考えて見たいと思う。