CDI(旧名WebBeans)入門 その3

の続き。

前回までは実装クラスそのものの注入であったが、今回はインターフェースからの注入をやってみる。

注入の際にセッターによるインジェクションを使うところは減ってると思うので、実装速度重視の現場ではあんまり必要としてないだろうなとは思いつつも、まったくないとは言い切れてないので。なんでもインターフェースってのはかなりなくなったよね?


まずはインターフェース。

package beans;

public interface HelloInterface {
    String getMessage(String name);
}


続いて実装クラス。

package beans;

public class Hello implements HelloInterface{

    public String getMessage(String name) {
        return "はろー" + name + " !";
    }

}


サーブレット

package servlet;

import beans.HelloInterface;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "HelloServlet", urlPatterns = {"/HelloServlet"})
public class HelloServlet extends HttpServlet {

    @Inject
    private HelloInterface hello;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet HelloServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>" + hello.getMessage("CDI") + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }
}

実行すると「はろー CDI !」と表示されます。

特に難しいことはないですね。ポイントはインターフェースと実装クラスを作っても何もする必要はないということ。自動的に実装クラスを探して注入してくれるようです。


では複数の実装クラスを用意するとどうなるでしょうか。

2つ目の実装クラスを作ります。

package beans;

public class Hello2 implements HelloInterface{

    public String getMessage(String name) {
        return "Hello " + name + " !";
    }
}

当たり前ですが、実行するとエラーが出ます。どっちを注入したらいいのかわからないからですね。

というわけでこの両者の違いを設定してあげる必要があります。そこで登場するのがNamedアノテーションです。

1つ目を以下のように修正。

import javax.inject.Named;

@Named("はろー1")
public class Hello implements HelloInterface{
〜略〜


2つ目を以下のように修正。

import javax.inject.Named;

@Named("はろー2")
public class Hello2 implements HelloInterface{
〜略〜

サーブレットを以下のように修正。

〜略〜
    @Inject
    @Named("はろー1")
    private HelloInterface hello1;
    
    @Inject
    @Named("はろー2")
    private HelloInterface hello2;

〜略〜
            out.println("<body>");
            out.println("<h1>" + hello1.getMessage("CDI") + "</h1>");
            out.println("<h1>" + hello2.getMessage("CDI") + "</h1>");
            out.println("</body>");

〜略〜

実行すると

はろーCDI !
Hello CDI !

と表示されます。簡単ですね。