Nanowebを強引に試してみる
codehausにホスティングされているNanoContainer関係のコンポーネント?ファミリ?のnanoweb(今はnanowarにマージされてるの?)を試してみた。
pserverが使えない環境からのアクセスなので distサーバからSNAPSHOTを拾ってきて動作させる。サンプルも置かれているが動作しない。どうも、
DefaultPicoContainer → DefaultSoftCompositionPicoContainer
とかしないと駄目だった。このへんはまだ揺れてるみたい。でもとりあえず試すだけだし。
20回ぐらい試行錯誤してついにコンテキストの起動に成功。さっそくブラウザでアクセス!おお、出来た!出来たとなったらさっそくソースを追いかけてみる。
まず nanowebでは groovyのクラスがそのままStrutsでいうところのActionに相当しているようだ。ソースの断片を見て見ると
[game.groovy] play() { . . return "input" }
などと定義されており、このメソッドひとつひとつがActionを司っている。そういう意味ではStrutsのActionとは違って 1:Nというのか、そんな感じになっているわけか。
クライアントからのリクエストはこんな感じだった。
http://localhost:8080/nanoweb/game/play.groovy
これで "game/play.groovy"を解釈してくれるServletが、最終的にはgame.groovyのplay()をinvokeする、と。なんかちょっとややこしいね。
で、groovyのメソッドのreturn "input" はそのまま Velocityのファイル名に対応しているわけですね。ビューとの値の受け渡しはどうやるんだろう?
[game_input.vm] <p> ${action.hint} </p> <form action="play.groovy"> <input name="guess" type="text" value="${action.guess}"/> <input type="submit" value="Guess"/> </form>
なるほど。Velocityのコンテキストに"action"がバインドされてるわけか。formのsubmit側は素直にnameに指定している、と。中身まだどうなってるか分からないけども action = game.groovyで定義しているクラスのインスタンス、となっている予感?
groovyは特になにも宣言しなければ
class Game { GUESS_NEW_HINT = "Guess a number between 1 and 20" NumberToGuess numberToGuess int guess = Integer.MIN_VALUE hint = GUESS_NEW_HINT
だけで、guessも hintも参照可能だから、ってことですかね。Javaから見たときのgroovyのこういうクラスはsetter/getterが自動的に定義されていたような気がします(ウソかもしれない)。
それだけか、と思ってたんですけど、さすがNanoContainerファミリ。
class Game { . NumberToGuess numberToGuess . . Game(NumberToGuess n) { numberToGuess = n } }
というわけで、このgroovyのクラス、constructor-based injectionなんですよ。で、このインジェクションにnanocontainer,picocontainerが活躍しているというわけですね。
はて、「コンポーネントの登録」はどこでしているのか…と思ったらこれはダサかった。
nanocontainer.groovy
まあ、要するにS2でいうところの app.diconみたいなことが書いてあるわけですね。ちなみに、このスクリプト部分は外部ファイルに持つこともできるので「ひどすぎ」ということはありません。でもなんかもうちょっとやり方ないのかなあ?? > ifの羅列部分とか
とりあえず動いたので今日はここまで。NanoWebが誇らしげに言うように、本当に設定ファイルはありませんが、上のコンポーネント登録のとこだけが引っかかる。