matsukaz's blog

Agile, node.js, ruby, AWS, cocos2d-xなどなどいろいろやってます

Spring 2.x & Struts 1.3.x 連携

Struts と Spring の連携方法にはいくつかパターンがあるけど、個人的にはやはり id:yohjizzz:20070109:1168319194 さんも紹介されてる AutowiringRequestProcessor を使うのが便利かなと。

ただし、AutowiringRequestProcessor は RequestProcessor を継承したクラスのため、Struts 1.3 で利用すると「Chain of Responsibility」パターンを利用したチェーン定義ができなくなっちゃいます。
せっかく Struts 1.3 を利用するんだから、やっぱりチェーン定義もできるようにしておきたいところ。

んで解決するためにやってみた方法は、

  • リクエストプロセッサは ComposableRequestProcessor を利用する。
  • チェーン定義で指定されている CreateAction クラスを継承し、Autowiring の処理を追加する。

というもの。
もしかしたらチェーン定義で CreateAction クラスのあとにAutowiring の処理を追加した Command インタフェースの実装を追加してもいけるのかもしんないけど、とりあえず分かりやすいのでこの方法で。

で、肝心の実装。
内容は AutowiringRequestProcessor とほぼ同じです。

public class AutowiringCreateAction extends CreateAction {
  private WebApplicationContext webApplicationContext;
  private int autowireMode;
  private boolean dependencyCheck;

  @Override
  protected synchronized Action getAction(ActionContext context, String type, ActionConfig actionConfig) throws Exception {

    Action action = super.getAction(context, type, actionConfig);
    webApplicationContext.getAutowireCapableBeanFactory().autowireBeanProperties(action, autowireMode, dependencyCheck);
    return action;
  }

  @Override
  protected Action createAction(ActionContext context, String type) throws Exception {

    ServletActionContext saContext = (ServletActionContext) context;
    ActionServlet actionServlet = saContext.getActionServlet();
    webApplicationContext = DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, context.getModuleConfig());

    if (webApplicationContext instanceof onfigurableApplicationContext)
      ((ConfigurableApplicationContext)webApplicationContext).getBeanFactory().ignoreDependencyType(ActionServlet.class);

    autowireMode = DelegatingActionUtils.getAutowireMode(actionServlet);
    dependencyCheck = DelegatingActionUtils.getDependencyCheck(actionServlet);

    return super.createAction(context, type);
  }
}

適用手順は chain-config.xml の CreateAction の指定をこのクラスにするだけ。これで Struts 1.3 のチェーン定義と Spring 2.0 の Autowiring の機能が両方使えます(^^
ちなみに Tiles を使う場合もこのままで問題ありませんでした。

Spring 2.1 でこのクラスを入れてくれないかなぁ。M1 では今まで通り AutowiringRequestProcessor しかなかった・・・。