Spring Boot DI/AOP

staticメソッド内でDIを利用してみた

例えば、staticメソッド内でデータベースアクセスをする等、staticメソッドからDIされるオブジェクトを呼び出したい場合もある。

しかし、DIされるオブジェクトのメソッドがstaticメソッドでないことが多いため、直接、staticメソッドからDIされるオブジェクトを呼び出すことができない。そこで、あらかじめDIされるオブジェクトをstatic変数で宣言し、その変数へのsetterメソッドを通してDIされるオブジェクトの生成が行えるようにする。

今回は、staticメソッド内でDIを利用するサンプルプログラムを通して、その実装方法を共有する。



前提条件

以下の記事のSpring BootのWEB画面用アプリが作成済であること。

IntelliJ IDEA上でGradleを使ってWeb画面のSpring Bootプロジェクトを作成してみたSpring Bootのプロジェクトを新規作成を「IntelliJ IDEA」のメニューから実施しようとしたところ、無料の「Commun...

やってみたこと

  1. DIに関連するクラスの作成
  2. コントローラクラス・HTMLの作成と動作検証

DIに関連するクラスの作成

今回は、staticメソッドをもつクラス内で、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を利用するプログラムの実行結果

要点まとめ

  • staticメソッドからDIされるオブジェクトのメソッドを呼び出すには、あらかじめDIされるオブジェクトをstatic変数で宣言し、その変数へのsetterメソッドを通してDIされるオブジェクトの生成が行えるようにする。