CDIの準備

今回はCDIです。

【前提条件】

[環境]

【概要】

今回はJavaEE6から追加されたCDIの環境設定です。

JavaEE5以前のバージョンでDIを行うためには
Spring、Seasar2などのDIコンテナが必要でした。

JavaEE6からはJava標準の仕様書としてDIが可能になりました。

【準備】

CDIを行うためにはbeans.xmlといわれるファイルを用意する必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd">
    
</beans>

beansタグの定義のみで中身は何も書く必要がありません。

beans.xmlの配置場所は下記の三つのうちいずれかの場所におきます。
 ■JARやEARなどのファイルのMETA-INFディレクトリ配下
 ■WEB-INFディレクトリ配下
 ■JVMクラスパスのMETA-INFディレクトリ配下

今回のサンプルはWEB-INF配下に置いています。

【サンプルコード】

[ManagedBean]

ユーザ一覧を表示するためのManagedBeanです。

package jp.glory.ui;

import java.util.List;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import jp.glory.application.UserApplication;
import jp.glory.infrastructure.persistence.entity.UserData;

@Named(value = "userListPage")
@RequestScoped
public class UserListPage {

    @Inject
    private UserApplication applicaiton = null;

    public List<UserData> getUserList() {
        return applicaiton.findAllList();
    }

}

オブジェクトをインジェクションする場合は
javax.inject.Injectアノテーションを使用します。
Injectアノテーションは属性を持たないので、アノテーションをつけるだけです。

サンプルのソースではManagedBeanアノテーションではなく、
javax.inject.Namedアノテーションを使用しています。

Namedアノテーションvalue属性には
XHTMLからEL式でアクセスする時の名称を指定します。

RequestScopedアノテーション
javax.enterprise.context.RequestScopedアノテーションを使用しています。
こちらはCDIによるスコープ管理です。

上記のコードは下記のコードとほぼ同じです。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name = "userListPage")
@RequestScoped
public class UserListPage {
    // 処理部分は省略
}
[実行クラス]

今回はインターフェイスとそれを実装するクラスの二つを作成します。
まずはインターフェイスからです。

package jp.glory.application;

import java.util.List;

import jp.glory.infrastructure.persistence.entity.UserData;

public interface UserApplication {

    List<UserData> findAllList();
}

特に何もない普通のインターフェイスです。

つづいてクラスです。

package jp.glory.application.impl;

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

import jp.glory.application.UserApplication;
import jp.glory.infrastructure.persistence.entity.UserData;

public class UserApplicationImpl implements UserApplication {

    @Override
    public List<UserData> findAllList() {

        final List<UserData> userList = new ArrayList<>();

        userList.add(createUserData("USER-0001", "Test01"));
        userList.add(createUserData("USER-0002", "Test02"));
        userList.add(createUserData("USER-0003", "Test03"));

        return userList;
    }

    private UserData createUserData(final String userId, final String name) {

        final UserData data = new UserData();

        data.setUserId(userId);
        data.setName(name);

        return data;
    }
}

こちらも普通のPOJOです。

UserDataクラスも普通のPOJOです。

package jp.glory.infrastructure.persistence.entity;

public class UserData {

    private String userId = null;

    private String name = null;

    // アクセサメソッドは省略
}
[ページ]

ユーザ一覧のページです。

<?xml version="1.0" encoding="UTF-8" ?>
<!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:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">
    <f:view>
        <h:form id="searchForm">
            <h:dataTable value="#{userListPage.getUserList()}" var="user">
                <h:column>
                    <f:facet name="header">
                        ユーザID
                    </f:facet>
                    <h:outputText value="#{user.userId}" />
                </h:column>
                <h:column>
                    <f:facet name="header">
                        ユーザ名
                    </f:facet>
                    <h:outputText value="#{user.name}" />
                </h:column>
            </h:dataTable>
        </h:form>
    </f:view>
</html>

EL式でNamedアノテーションで指定した名称を使用しています。

【実行】

画面にアクセスしてみます。

【まとめ】

CDIではInjectアノテーションを使用するだけで、
インジェクションされました。

これによってシンプルなクラス構成の場合は簡単にDIができるようになっています。