[Java][Spring Boot] 依存性注入(Dependency Injection)の使い方 - NetBeansで始めるSpring Boot (5)
Spring BootのDIは、どのように使えばよいのでしょうか。
はじめに、Spring Bootのドキュメントを読んでみます。
ビーンや注入される依存性の定義には、Springフレームワークの標準技術を随意に使用できます。簡単にいうと、ビーンを探索するために
@ComponentScan
を使っているものを探します。これは@Autowired
コンストラクタインジェクションとの組み合わせて動きます。前述で示唆したようにコードを構成(アプリケーションクラスをパッケージのルートに置く)していれば、
@ComponentScan
を引数無しで追加できます。すべてのコンポーネント(@Component
、@Service
、@Repository
、@Controller
等)は、自動的にSpringビーンとして登録されます。
@Service
ビーンの例です。コンストラクタでRiskAssessor
ビーンへの依存性を定義しています。
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
ビーンを欲しいところに@AutoWired
を付けておけば、うまいことやってくれるみたいです。
お試し
依存される側
コンポーネントを作成します。
src/main/java/com/example/component/HelloComponent.java
package com.example.component;
import org.springframework.stereotype.Component;
@Component
public class HelloComponent {
public String greet(String name) {
return "Hello " + name;
}
}
依存する側
/greet?name=hogehoge
というURLへのアクセスで、HelloComponent
を呼び出してみます。
src/main/java/com/example/controller/HelloController.java
package com.example.controller;
import com.example.component.HelloComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private final HelloComponent helloComponent;
@Autowired
public HelloController(HelloComponent helloComponent) {
this.helloComponent = helloComponent;
}
@RequestMapping("/greet")
public String greet(@RequestParam(value = "name", required = true) String name) {
return helloComponent.greet(name);
}
}
実行結果
こんなんできました。
スコープはどうなっているのか?
Java EEのCDIでは、アプリケーションスコープ(シングルトン)、リクエストスコープ、セッションスコープ、会話スコープ、依存スコープを定義できました。
ドキュメントによりますと、
- singleton
- prototype
必要とされる度にインスタンスが作成されます。 - request
- session
- globalSesion
- application
- websocket
があるみたいです。いっぱいですね。デフォルトではsingletonになるそうです。
さらには自前のスコープも定義できるとか。
下5つは、Webアプリケーションコンテキストでないと使用できないです。
使い方
スコープ | 使い方 |
---|---|
singleton | デフォルトなので、何もしなくてOK |
prototype | XMLで定義? @Scope("prototype") をつける? |
request |
@RequestScope アノテーションをつける |
globalSession | XMLで定義? |
application |
@ApplicationScope アノテーションをつける |
websocket | XMLで定義? |
スコープがかぶったらどうなる?
singletonにprototypeを注入したらどうなるのか?
TODO:
注入のしかた
次の場所に注入できます。
- コンストラクタ
- セッター
- プロパティ