読者です 読者をやめる 読者になる 読者になる

ひこぽんのーと

覚書と雑記です。

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

限定子について。
インターフェイスにつき複数の実装がある場合、限定子を使うと書いた。
けど、クラスを増やす事に限定子を作るのって「めんどくさい」と思った。
ならば、限定子は使い回せないか?と考えた。

というわけで、こんなサンプルを書いてみたのだが。

インターフェイス 
戦闘用艦艇を表す
package warship;

public interface IWarShip {
    public String getName();
    public String getType();
}
実装その1
艦種を表す抽象実装
駆逐艦重巡洋艦
package warship;

public abstract class ADestoryer implements IWarShip {
    public String getType() {
        return "駆逐艦";
    }
}
package warship;

public abstract class AHeavyCruiser implements IWarShip {
    public String getType() {
        return "重巡洋艦";
    }
}
実装その2
本実装。 各駆逐艦を表す。
同じインターフェイス(IWarShip, ADestoryer)の実装なので、限定子を付加する。
限定子の実装はここでは省略。
Eclipseのウィザードで作成済とする。
package warship.impl;

import warship.ADestoryer;
import warship.qualifier.First;

@RequestScoped
@First
public class Akatsuki extends ADestoryer {

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

}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.ADestoryer;
import warship.qualifier.Second;

@RequestScoped
@Second
public class Hibiki extends ADestoryer {

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

}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.ADestoryer;
import warship.qualifier.Third;

@RequestScoped
@Third
public class Ikazuchi extends ADestoryer {

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

}
package warship.impl;

import javax.enterprise.context.RequestScoped;

import warship.ADestoryer;
import warship.qualifier.Forth;

@RequestScoped
@Forth
public class Inazuma extends ADestoryer {

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

}
Managed Bean
艦艇を管理する艦隊クラス
4つのIWarShipのメンバにインジェクションしたいので、メンバに各限定子を追加している。
また、initメソッドに@PostConstructアノテーションがあるが、
これを付加したメソッドはインジェクション後に実行される。
ここでは、艦艇クラスが確定したら画面表示用の艦艇リストを初期化している、というわけだ。
package warship;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.inject.Inject;
import javax.inject.Named;

import warship.qualifier.First;
import warship.qualifier.Forth;
import warship.qualifier.Second;
import warship.qualifier.Third;

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

    @Inject
    @Second
    private IWarShip secondShip;
    
    @Inject
    @Third
    private IWarShip thirdShip;
    
    @Inject
    @Forth
    private IWarShip forthShip;
    
    private DataModel<IWarShip> shipList;
    
    private String fleetName;
    
    public Fleet() {
    }
    
    @PostConstruct
    private void init() {
       List<IWarShip> ships = new ArrayList<IWarShip>();
       ships.add(firstShip);
       ships.add(secondShip);
       ships.add(thirdShip);
       ships.add(forthShip);
       shipList = new ListDataModel<IWarShip>(ships);
       fleetName = "第六駆逐艦隊";
       
    }
    
    public DataModel<IWarShip> getShipList() {
        return shipList;
    }

    /**
     * fleetNameを取得します。
     * @return fleetName
     */
    public String getFleetName() {
        return fleetName;
    }

    /**
     * fleetNameを設定します。
     * @param fleetName fleetName
     */
    public void setFleetName(String fleetName) {
        this.fleetName = fleetName;
    }
}
テスト用JSF
艦隊をリスト表示する。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <h:outputStylesheet library="css" name="default.css" />
    <title>DIサンプル</title>
</h:head>
<h:body>
    <h:form id="form1">
        <h2><h:outputLabel value="#{fleet.fleetName}" /></h2>
        <h:dataTable var="item" value="#{fleet.shipList}" styleClass="table" headerClass="headerrow" rowClasses="oddrow,evenrow">
            <h:column>
                <f:facet name="header">No.</f:facet>
                <h:outputText value="#{fleet.shipList.rowIndex}" />
            </h:column>
            <h:column>
                <f:facet name="header">艦種</f:facet>
                <h:outputText value="#{item.type}" />
            </h:column>
            <h:column>
                <f:facet name="header">名前</f:facet>
                <h:outputText value="#{item.name}" />
            </h:column>
        </h:dataTable>
    </h:form>
</h:body>
</html>

実行すると駆逐艦クラスがインジェクションされて、こうなる。
f:id:nagamitsu1976:20150803142542p:plain

で、ここまでは前回のおさらいみたいなものだけど、
ここから先については、その4へ続く。