ushidayの日記

主に「IBMi」のメモに・・・

アーティファクトの勉強メモ

Grails徹底入門11章の続きを勉強しております。後半は、アーティファクトの勉強です。
先の章で、作成した「E-mail作成プラグイン」をアーティファクト化する内容です。
一通り読んでみましたが、E-mailぐらいの機能だとアーティファクトにする、メリットが正直ピンとこないです。プラグイン定義ファイルのdoWithSpringとdoWithDynamicメソッドで、出来た機能でも十分な気がしてしまいます。本当はもっと深い、アーティファクトの利用方法があると思うのですが、自分の発想ではとりあえず、思い浮かぶわけもなく、定義の仕方、使い方だけでもとりあえず勉強です。
ただ、アーティファクトにすることによって、groovyクラスに出来て、DSLでプロパティを定義できたり、アーティファクト作成コマンドが使えたりする事で、プラグインの裏だけでやっていた事が、Grailsの表面に表れた気が?します。そんなアーティファクトの勉強中に、少し引っかかったので、忘れないようにメモです。

プラグイン定義ファイル(〜GrailsPlugin.groovy)でアーティファクトのリロードイベント(onChangeクロージャ)を勉強していると、以下のような記述が出てきました。

------ 省略(〜GrailsPlugin.groovy) -------
def onChange = { event ->

if (application.isArtefactOfType(EmailArtefactHandler.TYPE,event.source)){

	def em = application.addArtefact(EmailArtefactHandler.TYPE,event.source)
	def beans = beans{
		// ビーンの内容を再度設定
		"send${em.shortName}"(org.springframework.mail.SimpleMailMessage){ bean ->
		bean.parent = ref("abstractMailMessage")
		if (em.getPropertyValue("subject")) subject = em.getPropertyValue("subject")
		if (em.getPropertyValue("from")) from = em.getPropertyValue("from")
		if (em.getPropertyValue("to")) to = em.getPropertyValue("to")
		if (em.getPropertyValue("cc")) cc = em.getPropertyValue("cc")
		if (em.getPropertyValue("bcc")) bcc = em.getPropertyValue("bcc")
		if (em.getPropertyValue("replyTo")) replyTo = em.getPropertyValue("replyTo")
		if (em.getPropertyValue("sentDate")) sentDate = em.getPropertyValue("sentDate")
		}
	}

	// クラスの確認
	println beans.class		// grails.spring.BeanBuilder

	// コンテキストにビーンを再登録
	if (event.ctx){
		beans.registerBeans(event.ctx)
	}

}

}
  • 疑問1:「"def beans"で定義した変数が、その後、beans.registerBeansメソッドが使えているのは何故?」
  • 疑問2:「そもそも"def beans="の後の突然現れた、”beans”メソッドは、クロージャーを引数にしてビーンを再定義しているのは、解るけど何処から発生しているの?」

この悩みがスッキリせずに、前に進むのはどうも躊躇いがあり、調べてみました。今までも”application”プロパティなどが、定義せず使えた事と同じなのだろうけど、実態がやっぱり気になります。
で結局、ソースを調べてみると、「org.codehaus.groovy.grails.plugins.DefaultGrailsPlugin」で”beans”メソッドの定義はされていて、戻り値は”grails.spring.BeanBuilder”でした。

------ 省略(DefaultGrailsPlugin.java) -------
public BeanBuilder beans(Closure closure) {
    BeanBuilder bb = new BeanBuilder(getParentCtx(), new GroovyClassLoader(application.getClassLoader()));
    bb.invokeMethod("beans", new Object[]{closure});
    return bb;
}

ついでにソースを覗いていると「doWith〜」とか、「get〜(プラグイン情報)」があったり、コンストラクタの引数に”pluginClass”が渡されて、「evaluate〜」で、プロパティを設定してたりしてそうな...そんな感じでした。
「DefaultGrailsPlugin」が、基盤となってプラグイン定義ファイルが動いてそうなのが、何となく解ったような気がしました。「DefaultGrailsPlugin」の方が実態で、「〜GrailsPlugin.groovy」は、まさに定義ファイルという事なのかな?コードリーディングをすると、こういう部分が理解されてパワーになるんだろうなぁ。