S2Container の初期化
前回までで Seasar ではどのようにコンポーネントが生成されるのかが分かりました。まず、今回 Seasar のエントリ・ポイントは SingletonS2ContainerFactory#init() でした。ここで dicon ファイルの解析が行われて S2Container が生成され、 ComponentDef が S2Container に登録されるのでした。でも、恐らくコンポーネントは最初にコンテナを作った時点でコンテナに配置される筈です。SingletonS2ContainerFactory#init() を見てみましょう。
/** * 設定ファイルに基づいてS2コンテナを生成・初期化し、それを保持します。 既にS2コンテナが保持されている場合は何もしません。 * <p> * S2コンテナを生成した後、 初期化を行なう前に必要に応じて、 * 外部コンテキストおよび外部コンテキストコンポーネント定義レジスタをS2コンテナに設定します。 * </p> * * @see S2ContainerFactory#create(String) * @see org.seasar.framework.container.ExternalContext * @see org.seasar.framework.container.ExternalContextComponentDefRegister */ public static void init() { container = S2ContainerFactory.create(configPath); if (container.getExternalContext() == null) { if (externalContext != null) { container.setExternalContext(externalContext); } } container.init(); }
良く見ると S2Container#init() が呼び出されています。ここではクラスローダの設定や ComponentDef#init() が呼び出されています。クラスローダの設定については、Seasar はホットデプロイの影響などでややこしくなっていると思われるの省略します(分かる自信も無い・・・)。ComponentDef#init() では、実装クラスの取得および ComponentDeployer の準備が行われます。ComponentDefImpl#init() を見てみましょう。
public void init() { getConcreteClass(); getComponentDeployer().init(); }
getConcreteClass() では、アスペクトの適用を行って具象クラスを設定しています。これにより Seasar で管理されるコンポーネントは全てアスペクトの対象になるわけですね。まさにここ、AopProxy が Seasar におけるアスペクトを織り込むポイントになっているようです。この点については後ほど暇があったら見てみたいなーと思います。
public Class getConcreteClass() { concreteClass = AopProxyUtil.getConcreteClass(this); return concreteClass; }
/** * 完全なクラスを返します。 * * @param componentDef * @return 完全なクラス */ public static Class getConcreteClass(final ComponentDef componentDef) { final Map parameters = new HashMap(); parameters.put(ContainerConstants.COMPONENT_DEF_NAME, componentDef); AopProxy proxy = new AopProxy(componentDef.getComponentClass(), getAspects(componentDef), getInterTypes(componentDef), parameters); return proxy.getEnhancedClass(); }
次に ComponentDeployer#init() が実行されており、Seasar デフォルト設定の(つまり、コンテナの管理するインスタンスはシングルトンとして扱う)場合には、この段階でコンポーネントのデプロイが行われます。つまり、SingletonS2ContainerFactory#init() が実行されると、コンポーネントがコンテナにデプロイされているわけですねー。