🐱 うさねこ教室 Python と可観測性の教室

Spring Boot と DI

🐱 この章の目次

JVM の FastAPI

Spring Boot は JVM エコシステムで最も広く使われている Web フレームワークです。 Python における FastAPI のポジションに相当しますが、エンタープライズ機能がはるかに充実しています。 設定より規約(Convention over Configuration)を重視し、最小限のコードでアプリケーションを起動できます。

Dependency Injection(DI)

Spring の核となるのが DI(依存性注入) です。 FastAPI の Depends() はリクエストごとに依存を解決しますが、Spring の IoC コンテナ はアプリケーション起動時にすべての依存関係を構築・管理します。 クラス間の依存がフレームワークによって自動的に注入されるため、テスト時のモック差し替えが容易です。

アノテーションによる宣言

Spring Boot では アノテーション でクラスの役割を宣言します。

アノテーション役割FastAPI 相当
@RestControllerHTTP エンドポイント@app.get() デコレータ
@Serviceビジネスロジック特になし(通常のクラス)
@Autowired依存の注入Depends()
@SpringBootApplicationエントリーポイントapp = FastAPI()

コード比較: REST エンドポイント

// Kotlin + Spring Boot
@RestController
@RequestMapping("/users")
class UserController(
    private val userService: UserService  // DI で自動注入
) {
    @GetMapping("/{id}")
    fun getUser(@PathVariable id: Long): UserResponse {
        return userService.findById(id)
    }

    @PostMapping
    fun createUser(@RequestBody request: CreateUserRequest): UserResponse {
        return userService.create(request)
    }
}

@Service
class UserService(private val userRepository: UserRepository) {
    fun findById(id: Long): UserResponse = ...
    fun create(request: CreateUserRequest): UserResponse = ...
}
# FastAPI(比較用)
from fastapi import FastAPI, Depends

app = FastAPI()

def get_user_service() -> UserService:
    return UserService(repository=UserRepository())

@app.get("/users/{user_id}")
def get_user(user_id: int, service: UserService = Depends(get_user_service)):
    return service.find_by_id(user_id)

@app.post("/users")
def create_user(request: CreateUserRequest, service: UserService = Depends(get_user_service)):
    return service.create(request)

Auto-configuration

Spring Boot の Auto-configuration は、クラスパス上のライブラリを検出して自動的に設定を行います。 たとえばデータベースドライバが依存関係にあれば、DataSource が自動で構成されます。 FastAPI で言えば、pip install databases しただけでコネクションプールが自動設定されるようなイメージです。

// application.yml に書くだけで DB 接続が構成される
// spring:
//   datasource:
//     url: jdbc:postgresql://localhost:5432/mydb
//     username: user
//     password: pass

Spring Boot の起動コマンドは Gradle を通じて実行します。

./gradlew bootRun  # uvicorn main:app --reload に相当