例えば、staticメソッド内でデータベースアクセスをする等、staticメソッドからDIされるオブジェクトを呼び出したい場合もある。
しかし、DIされるオブジェクトのメソッドがstaticメソッドでないことが多いため、直接、staticメソッドからDIされるオブジェクトを呼び出すことができない。そこで、あらかじめDIされるオブジェクトをstatic変数で宣言し、その変数へのsetterメソッドを通してDIされるオブジェクトの生成が行えるようにする。
今回は、staticメソッド内でDIを利用するサンプルプログラムを通して、その実装方法を共有する。
 
 
前提条件
以下の記事のSpring BootのWEB画面用アプリが作成済であること。

やってみたこと
DIに関連するクラスの作成
今回は、staticメソッドをもつクラス内で、DIされる側のクラスのメソッド呼び出しを行った。今回作成したプログラム構成は以下の通り。
 
また、「DemoUtil.java」「DemoComponent.java」の内容は以下の通り。
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
 * staticメソッドからDIによるオブジェクトのメソッドを呼び出すサンプル
 */
@Component
public class DemoUtil {
    /** staticメソッドから呼び出せるよう、DIするオブジェクトをstatic変数で宣言 */
    private static DemoComponent demoComponent;
    /**
     * Spring Boot起動時に、DIするオブジェクトを生成し、先ほど宣言したstatic変数に設定
     * @param demoComponent DemoComponentインスタンス
     */
    @Autowired
    public void setDemoComponent(DemoComponent demoComponent){
        DemoUtil.demoComponent = demoComponent;
    }
    /**
     * DemoComponentオブジェクトからメッセージを取得するメソッドを呼び出す
     * @return 取得したメッセージ
     */
    public static String getMessage(){
        return demoComponent.getMessageFromComponent();
    }
}
package com.example.demo;
import org.springframework.stereotype.Component;
@Component
public class DemoComponent {
    public String getMessageFromComponent(){
        return "このメッセージはDemoComponentから取得しました";
    }
}
上記プログラムのように、staticメソッドをもつクラス(DemoUtil.java)に内でDIされる側のクラス(DemoComponent.java)のstatic変数を用意しておき、Spring Boot起動時にそのstatic変数にDIするオブジェクトを設定されるようにしておけば、staticメソッドをもつクラス内で、DIされる側のクラスのメソッドを呼び出すことができる。
コントローラクラス・HTMLの作成と動作検証
今回は、コントローラクラス(DemoController.java)の中で、staticメソッドをもつクラス(DemoUtil.java)のメソッドを呼び出し、呼び出した結果をmsgオブジェクトに格納し、それをHTML(index.html)で表示した。
「DemoController.java」「index.html」の内容は以下の通り。
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class DemoController {
    @RequestMapping("/")
    public ModelAndView index(ModelAndView mav){
        String str = DemoUtil.getMessage();
        mav.addObject("msg", str);
        mav.setViewName("index");
        return mav;
    }
}
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index page</title>
</head>
<body>
    メッセージの取得結果:
    <p th:text="${msg}">ここに設定したメッセージが設定されます</p>
</body>
</html>
その他のソースコード内容は、以下のサイトを参照のこと。
 https://github.com/purin-it/java/tree/master/di-in-static-method/demo
 
 
その後、Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした結果は以下の通りで、staticメソッドをもつクラス(DemoUtil.java)のメソッドを呼び出した結果が、画面上に表示されることを確認した。
 
要点まとめ
- staticメソッドからDIされるオブジェクトのメソッドを呼び出すには、あらかじめDIされるオブジェクトをstatic変数で宣言し、その変数へのsetterメソッドを通してDIされるオブジェクトの生成が行えるようにする。






