Spring Core Concepts
この文書 は Spring Framework の核心概念 を学習順序 に従 って整理 しています。
Spring と JakartaEE
Spring は複数 の JakartaEE (J2EE) 標準 を統合 しています:
- Servlet API (JSR 340)
- WebSocket API (JSR 356)
- Concurrency Utilities (JSR 236)
- JSON Binding API (JSR 367)
- Bean Validation (JSR 303)
- JPA (JSR 338)
- JMS (JSR 914)
- Dependency Injection (JSR 330) と Common Annotations (JSR 250) を支援 。
Spring IoC
Inversion of Control: オブジェクトの作成 と依存関係管理 の権限 を、開発者 から Spring コンテナに移転 すること。
**制御
の反転
**:オブジェクトの制御権
をサードパーティのコンテナ(IoC コンテナ)に移転
するという設計思想
です。
IoC コンテナの種類
BeanFactory: 基本 インターフェース、高度 な設定 メカニズムを提供 。ApplicationContext:BeanFactoryのサブインターフェース、AOP 統合 、メッセージ処理 、イベント発行 などのエンタープライズ機能 を追加 。
Spring DI
Dependency Injection: IoC を実現 する具体的 な技術 。
- オブジェクトは自身 で依存関係 を作成 せず、コンテナによって注入 されます(制御 の反転 )。
- 利点 : テストが容易 (モックオブジェクトの注入 )、疎結合 、構成 の柔軟性 。
**依存性注入
**:被依存
オブジェクトを(IoCコンテナを介
して)受動的
に受信
オブジェクト中
に注入
すること。
注入方式
- Setter 注入
:
setXXX()メソッドを使用 。 - Constructor 注入 : コンストラクタを使用 。
- 自動
ワイヤリング (Autowire):
byType: 属性 の型 で検索 。byName: 属性名 (Bean ID)で検索 。
Java EE 6 CDI vs Spring DI
| 機能 | Java EE 6 CDI | Spring DI |
|---|---|---|
| 標準化 | Java 標準 API (CDI 仕様 )。 | サードパーティフレームワーク。 |
| アノテーション | アノテーション数 が少 なく、システムが単純 。 | アノテーション種類 が豊富 で強力 だが複雑 。 |
| 構成 | 硬直的 だが理解 しやすい。 | 柔軟 な XML/Java 構成 。 |
Spring Bean
- Spring IoC コンテナによって管理 されるすべての Java オブジェクト。
Bean Scope
Singleton: グローバルシングルトン。Prototype: 要求 ごとに新 しいインスタンスを作成 。- Web 専用
:
Request,Session,Application,WebSocket。
Spring Bean Lifecycle
4 つの主要段階 :
- 実体化 (Instantiation)
- 属性設定 (Populate)
- 初期化 (Initialization)
- 破棄 (Destruction)
簡易フローチャート
flowchart LR c[Constructor] a[Autowired] p[PostConstruct] i[InitializingBean] app[ApplicationRunner] cli[CommandLineRunner] c --> a --> p --> i --> app --> cli
詳細フローチャート
flowchart TB
subgraph Instantiation_実体化
Constructor
end
subgraph Population_Of_Properties_属性設定
Setter_Injection
end
subgraph BeanNameAware_Bean名設定
setBeanName
end
subgraph setBeanFactory_工場設定
BeanFactoryAware
end
subgraph ApplicationContext_文脈設定
setApplicationContext
end
subgraph BeanPostProcessor_前処理
postProcessBeforeInitalization
end
subgraph PostConstruct_注釈初期化
init_method
end
subgraph InitializingBean_面初期化
afterPropertiesSet
end
subgraph Custom_Initialization_独自初期化
custom_init_method
end
subgraph postProcess_AfterIntialization_後処理
p_BeanPostProcessor
end
subgraph PreDestroy_予備破棄
destroy_method
end
subgraph DisposableBean_面破棄
destroy_method
end
subgraph Custom_Destruction_独自破棄
Custom_Destroy_Method
end
Instantiation_実体化 ==> Population_Of_Properties_属性設定 ==> BeanNameAware_Bean名設定
BeanNameAware_Bean名設定 ==> setBeanFactory_工場設定 ==> ApplicationContext_文脈設定
ApplicationContext_文脈設定 ==> BeanPostProcessor_前処理 ==> PostConstruct_注釈初期化 ==> InitializingBean_面初期化
InitializingBean_面初期化 ==> Custom_Initialization_独自初期化 ==> postProcess_AfterIntialization_後処理
postProcess_AfterIntialization_後処理 ==> PreDestroy_予備破棄 ==> DisposableBean_面破棄
DisposableBean_面破棄 ==> Custom_Destruction_独自破棄

ApplicationContextAware インターフェース
このインターフェースを実装 する Bean は、起動時 に
ApplicationContextへの参照 を取得 できます。
- Use Case (使用例
)
- イベントリスナーで、ビジネスロジックに基 づいて Bean を動的 に取得 する必要 がある場合 (循環依存 を避 けるためなど)。
- ユーティリティクラス(Helper Class)で、静的 メソッドから Spring 管理 のサービスにアクセスする場合 。
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return appContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) appContext.getBean(name);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
Map beanMaps = appContext.getBeansOfType(clazz);
if (beanMaps != null && !beanMaps.isEmpty()) {
return (T) beanMaps.values().iterator().next();
} else {
return null;
}
}
private static void checkApplicationContext() {
if (appContext == null) {
throw new IllegalStateException("applicationContext has not been injected yet.");
}
}
}Spring AOP
プロキシパターンを使用 して、ログやセキュリティなどの機能 を横断的 に適用 します。ビジネスロジックと基盤 インフラの関心事 を分離 。
flowchart LR 0((AOP)) --> 1([Around 前置処理]) --> 2([Before]) --> 3[Target Object] --> 4([AfterReturning]) --> 5([After]) --> 6([Around 後置処理])
CGLIB プロキシ
Code Generation Library
CGLIB は高性能
なコード生成
ライブラリです。Spring AOP では、ターゲットオブジェクトがインターフェースを実装
していない場合
、Spring は自動的
に CGLIB を使用
してプロキシオブジェクトを作成
します。ターゲットクラスを継承
してプロキシを実装
するため、final クラスやメソッドはプロキシできません。
Transaction
Propagation
@Transactional(propagation = Propagation.REQUIRED)
| パラメータ | 説明 |
|---|---|
REQUIRED | デフォルト。既存 があれば参加 、なければ新規作成 。 |
SUPPORTS | 既存 があれば参加 、なければ非 トランザクションで実行 。 |
MANDATORY | トランザクション内 での実行 が必須 、無 ければ例外 をスロー。 |
REQUIRES_NEW | 現在 のを中断 し、完全 に独立 したものを作成 。 |
NOT_SUPPORTED | 非 トランザクションで実行 、現在 のは一時停止 。 |
NEVER | トランザクション内 での実行 を禁止 、有 れば例外 をスロー。 |
NESTED | ネストされたトランザクション(子 のロールバックは親 に影響 しないが、親 のロールバックは子 に影響 )。 |
動作比較例
- REQUIRED: A メソッドが B メソッドを呼 び出 す、両者 は同 じトランザクション内 。B がエラーなら全体 ロールバック。
- REQUIRES_NEW: A メソッドが B メソッドを呼 び出 す、B は独立 トランザクションを開始 。B のロールバックは A に影響 しない。
- NESTED: A メソッドが B メソッドを呼 び出 す、B は A の子 トランザクション。B のエラーは個別 にロールバック可能 (Catch 必要 )。
適用シナリオ (Use Case)
- 独立
ログ記録
: ビジネス失敗
でもログ記録
が必要
な場合
、ログサービスは
REQUIRES_NEWに設定 。 - 複雑
なビジネス補償
: 注文
メインフローとポイント付与
、ポイント失敗
で注文
が失敗
すべきでない場合
、
NESTED+ Try-Catch を使用 。
@Transactional(propagation = Propagation.REQUIRED)
public void mainProcess() {
orderService.saveOrder(); // 成功
try {
logService.log(); // REQUIRES_NEW に設定、A がロールバックしてもログは残る
} catch (Exception e) {}
}WebSocket API
flowchart TB HTTP握手攔截器[HttpSessionHandshakeInterceptor] HTTP握手前[beforeHandshake] HTTP握手後[afterHandshake] WssText處理器[TextWebScoketHandler] 是否支持內容拆分[supportPartialMessages] Wss連線建立後[afterConnectionEstablished] Wss連線關閉後[afterConnectionClosed] HTTP握手攔截器 --> HTTP握手前 --> HTTP握手後 --> WssText處理器 --> 是否支持內容拆分 --> Wss連線建立後 --> Wss連線關閉後