Search on the blog

2013年1月27日日曜日

Learn Struts(7)

Strutsで作成するアプリからlog4jを使えるようにしてみました。
せっかくなので、ApacheのCommons Loggingを通してlog4jを使ってみます。

設定
1. まずlog4j.jarをWebContent/WEB-INF/libにコピペします。(commons-logging.jarはstruts-blankをインポートすれば最初からWebContent/WEB-INF/libに入っています。)

最初$CATALINA_BASE/libに入れていたのですが、特定のアプリケーションからのみ参照できるようにしたい場合は、WEB-INF/libに入れるのが慣例のようです。
Eclipseを使ってる場合はBuild Pathからライブラリ追加しても使えないので注意してください。Tomcatが参照できる場所に置かないといけません。

2. log4j.xmlをsrcに置きます。

3. commons-logging.propertiesをsrcに置きます。中身は、
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
とします。

動作確認
簡単に確認できればいいので、生成したloggerのクラス名を表示するアクションクラスを作りました。
[TestAction.java]
public class TestAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        
        Log logger = LogFactory.getLog(TestAction.class);
        System.out.println(logger.getClass());
        
        return null;
    }

}
[実行結果]
[INFO ] 2013-01-27 00:01:50 org.apache.struts.chain.ComposableRequestProcessor::init() - Initializing composable request processor for module prefix ''
[INFO ] 2013-01-27 00:01:50 org.apache.struts.chain.commands.servlet.CreateAction::createAction() - Initialize action of type: main.TestAction
class org.apache.commons.logging.impl.Log4JLogger

お、Log4JLoggerクラスのloggerインスタンスが生成できているようです。
strutsの内部のロギングもlog4jになってる。。log4j.xmlで別のlogger定義した方がよさそうですね。

仕組み
とりあえずソース読んだり、デバッグ実行したりして理解したことです。
  • Jdk14Loggerはadapterの役割を果たし、log4jのロガーをcommons-loggingLogインターフェースで扱えるようにする。
  • LogFactoryインターフェースを継承したlog4j専用のファクトリーを作成することで、log4jのロガーを取り出せるようにする。これは、Abstract Factory patternですかね。
  • と思いきや、log4jのファクトリであるLog4jFactoryは@depricatedになっている。結局ファクトリクラスはLogFactoryImplしかなくて、ここで使用するログを切り替える処理が入っている。
  • LogFactoryImpl#newInstanceFactoryでプロパティファイルから使用するロガーのクラス名を取得。このクラス名を元に使いたいロガーのクラスをクラスローダにあげて、リフレクションでコンストラクタとってきて、・・っていう処理を行う。
デザインパターン勉強してたおかげで、やりたいことはスッと入ってきた。クラスローダの仕組みがいまいち分かってないから勉強したい。

0 件のコメント:

コメントを投稿