Springフレームワークの基本的な動作を理解するために、3つの主要なクラスについて詳しく見ていきます。
Bean定義管理クラス
BeanSpec
BeanSpecは、Beanに関する詳細情報を保持するためのクラスです。このクラスでは、Beanのプロパティやメソッドなどの情報を記録します。例えば、Beanが持つフィールドやメソッドの一覧などが含まれます。
Bean登録処理クラス
BeanSpecRegistrar
BeanSpecRegistrarは、外部から取得したBean定義をSpringコンテナに登録する役割を持っています。通常、XMLファイルやデータベース、YML設定ファイルなどからBean定義を読み込み、それをSpringのIoCコンテナに登録します。
内部的には、BeanFactoryのMap<String, BeanSpec>にこれらの定義が保存されます。
public interface BeanSpecRegistrar {
/**
* 指定された名前でBean定義を登録します。
*/
void register(String beanName, BeanSpec beanSpec) throws BeanRegistrationException;
/**
* 指定された名前のBean定義を削除します。
*/
void deregister(String beanName) throws NoSuchBeanException;
/**
* 指定された名前のBean定義を取得します。
*/
BeanSpec retrieve(String beanName) throws NoSuchBeanException;
/**
* 登録済みのBean定義が存在するか確認します。
*/
boolean isRegistered(String beanName);
/**
* 登録されているすべてのBean名を返します。
*/
String[] getAllBeanNames();
}
疑問点:
BeanSpecRegistrarとBeanFactoryはどのように連携しているのでしょうか? 解答: 多くの場合、DefaultBeanFactoryのような実装クラスが両方のインターフェース(BeanSpecRegistrarとBeanFactory)を実装しており、内部でthis.beanSpecMapを利用してBean定義を操作しています。
Bean生成・管理クラス
BeanManager
BeanManagerは、Springアプリケーション内のBeanインスタンスを管理する責任を持っています。IoC(制御の逆転)コンテナの基本機能を提供し、Beanの作成、設定、管理を行います。
主な機能:
- Beanのインスタンス化
- Bean定義に基づいてBeanインスタンスを作成します。これはコンストラクタやファクトリメソッドを使用して行われます。
- 依存性注入
- Bean間の依存関係を解決し、必要なインスタンスを注入します。主にコンストラクタ注入やSetterメソッド注入を利用します。
- ライフサイクル管理
- Beanのライフサイクル全体を管理します。初期化や破壊時のコールバックメソッド(例:
init-method,destroy-method)をサポートします。
- シングルトンキャッシュ
- シングルトンBeanは通常キャッシュされ、同じインスタンスが繰り返し使用されます。これによりパフォーマンス向上が図られます。
- エイリアス解決
- 同じBeanに対して複数の名前を設定できるため、どの名前でも同じインスタンスを取得できます。
- 遅延初期化
- 必要になるまでBeanインスタンスを作成せず、リソースの無駄を防ぎます。
- 型安全な検索
- 型指定によるBean検索が可能です。たとえば、
getBean(Class requiredType)を使用して特定の型のBeanを取得できます。
public interface BeanManager {
// 指定された名前でBeanインスタンスを取得
Object fetchBean(String name) throws BeanException;
// 指定された名前と型でBeanインスタンスを取得
<T> T fetchBean(String name, Class<T> type) throws BeanException;
// 指定された型でBeanインスタンスを取得
<T> T fetchBean(Class<T> type) throws BeanException;
// 指定された名前のBeanが存在するか確認
boolean hasBean(String name);
// 指定された名前のBeanがシングルトンかどうか
boolean isSingleton(String name) throws NoSuchBeanException;
// 指定された名前のBeanがプロトタイプかどうか
boolean isPrototype(String name) throws NoSuchBeanException;
// 指定された名前のBeanが指定された型と一致するか
boolean matchesType(String name, Class<?> typeToMatch) throws NoSuchBeanException;
// 指定された名前のBeanの型を取得
Class<?> getType(String name) throws NoSuchBeanException;
// 指定された名前のBeanのエイリアスを取得
String[] getAliases(String name);
}