GrailsでSpringをGroovyにしよう!

47
GrailsでSpringを Groovyにしよう! JSUG+JGGUG合同勉強会 2009年6月24日 def speaker = new Cast(name:”T.Yamamoto”,version:”JSG2UG-2009-06-24”)

description

JSUG+JGGUG合同勉強会 2009年6月24日

Transcript of GrailsでSpringをGroovyにしよう!

Page 1: GrailsでSpringをGroovyにしよう!

GrailsでSpringをGroovyにしよう!

JSUG+JGGUG合同勉強会

2009年6月24日

def speaker = new Cast(name:”T.Yamamoto”,version:”JSG2UG-2009-06-24”)

Page 2: GrailsでSpringをGroovyにしよう!

自己紹介名前:山本 剛 (やまもとつよし)所属:株式会社ニューキャスト組版屋、印刷系Webアプリ開発など。案件は90%Grailsを使ってます。

JGGUG(じぇいがぐ) 名古屋支部 担当です。「Grails徹底入門」9-11章を書きました。 Grails Acegi Plugin作った人。

ブログhttp://d.hatena.ne.jp/mottsnite/

Page 3: GrailsでSpringをGroovyにしよう!

おさらい

Page 4: GrailsでSpringをGroovyにしよう!

Grailsとは?よく聞く説明「Groovyで実装されたRuby on Rails」!?  Java+Groovyで実装された、CoC、DRYの概念を取り入れた(‘RoR’にインスパイアされた)、Webアプリケーション開発環境。基礎はSpring,Hibernate等を使用している。

そして、それらをシンプルに活用できる環境。

Grails, the Platform (DGG2引用)

合ってるようで間違い

Page 5: GrailsでSpringをGroovyにしよう!

Grailsの構成図GrailsGrailsGrails Groovy

Spring Hibernate SiteMeshGroovy

基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)JVMJVMJVMJVM

Hibernate:ORマッピング Spring: DIコンテナ・多機能なラッパーフレームワーク SiteMesh:レイアウトフレームワーク Jetty: サーブレットコンテナ HSQLDB:ピュアJavaなデータベース

2.5.6

3.3.1 2.4

1.5+

1.6.3

Page 6: GrailsでSpringをGroovyにしよう!

デモgrails create-app democd demograils create-domain-class Bookgrails create-controller Bookgrails run-app

今日はこれやりません

Page 7: GrailsでSpringをGroovyにしよう!

本日のテーマ!

GrailsとSpringの関係~BeanBuilderへたどりつくまで。BeanBuilder(ビーンビルダ)解説!←本日のメイン

GrailsでSpringをGroovyに使う!GrailsにSpringビーンを追加してみる。

SpringでGrailsを使ってGroovyに!applicationContext.groovy !?!? (サンプル解説)GORMをSpringで使う!(サンプル解説)

「GrailsでSpringをGroovyにしよう!」

Page 8: GrailsでSpringをGroovyにしよう!

BeanBuilderって?いろいろ話す前に、まずはザックリこんな感じ。

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="127.0.0.1"/> </bean> <bean id="mailMessageMe" class="org.springframework.mail.SimpleMailMessage"> <property name="from" value="[email protected]"/> </bean><bean id="mailMessageYou" class="org.springframework.mail.SimpleMailMessage"> <property name="from" value="[email protected]"/> </bean>

mailSender(org.springframework.mail.javamail.JavaMailSenderImpl) { host = '127.0.0.1' }def map = ["Me":"[email protected]","You":"[email protected]"]map.each{k,v-> "mailMessage${k}"(org.springframework.mail.SimpleMailMessage) { from = v }}

ダイナミックにしてみたり!

Page 9: GrailsでSpringをGroovyにしよう!

何故,

BeanBuilder

!?

Page 10: GrailsでSpringをGroovyにしよう!

GrailsとSpringの関係今さら言うまでもなく、Grailsの中はSpringがいっぱい!基礎をSpringフレームワークが支えています。Grailsには、Springビーンを簡単に追加する仕組みがあります。 → 「GrailsでSpringをGroovyに使う!」で話します。

先ずは関係を知るために簡単な所から見てみましょう。PROJECT_HOME/src/templates/war/web.xmlPROJECT_HOME/web-app/WEB-INF/applicationContext.xml 手 順

grails create-app democd demograils install-template

Page 11: GrailsでSpringをGroovyにしよう!

src/templates/war/web.xml<web-app version="2.4"... <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param>... <servlet> <servlet-name>grails</servlet-name> <servlet-class>org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet>...

applicationContext!

DispatcherServlet!

Page 12: GrailsでSpringをGroovyにしよう!

web-app/WEB-INF/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"...> <bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean"> <description>Grails application factory bean</description> <property name="grailsDescriptor" value="/WEB-INF/grails.xml" /> <property name="grailsResourceLoader" ref="grailsResourceLoader" /> </bean>...</beans>

Page 13: GrailsでSpringをGroovyにしよう!

applicationContext.xmlの中身grailsApplication - GrailsApplicationFactoryBeanpluginManager - GrailsPluginManagerFactoryBeanpluginMetaManager - DefaultPluginMetaManagergrailsConfigurator - GrailsRuntimeConfiguratorgrailsResourceLoader - GrailsResourceLoaderFactoryBeangrailsResourceHolder - GrailsResourceHoldercharacterEncodingFilter - CharacterEncodingFilter

Page 14: GrailsでSpringをGroovyにしよう!

その中で、最も重要なのは、

grailsApplication

GrailsApplicationFactoryBean

Page 15: GrailsでSpringをGroovyにしよう!

GrailsApplicationFactoryBeanGrailsの最初のバージョンからあります。GroovyファイルからGrailsアプリケーション用オブジェクトを生成するファクトリビーン。リソースが読みこまれ、ここから様々なGrailsオブジェクトが出荷されます。

grailsApplicationgrails-app以下のgroovyファイル達grails-app/domin/Book.groovy Author.groovygrails-app/service/SomeService.groovy HogeService.groovy

リソースロード

ここから様々な情報を読みこんで、Grailsで使うビーンの生成をしています。

Page 16: GrailsでSpringをGroovyにしよう!

grailsApplicationとビーン生成の関係この関係を調べることでBeanBuilderって何か解るかも!いろいろソースを探ってたらBeanBuilder誕生の理由?が解った気がしたから・・・但し、推測

Page 17: GrailsでSpringをGroovyにしよう!

Grailsの裏側解説(簡易版)

groovygroovygroovygroovy

groovygroovygroovygroovy

grails-appの中

grails起動

リソースロード

grailsApplicationに収集

ルールに基づいて情報を読みこむ

コンテキスト完成

ビーンが生成される

Page 18: GrailsでSpringをGroovyにしよう!

歴史をさかのぼると、v0.2時代はGrailsのGroovy(CoC)な部分は複雑だった。

Grailsの裏側解説(簡易版)

GrailsPlugin

grailsApplicationgrails-app以下のgroovyファイル達grails-app/domin/Book.groovy Author.groovygrails-app/service/SomeService.groovy HogeService.groovy

リソースロード

・ロードされたリソースをgrailsApplicationから用途別に収集・クラス名とかプロパティ内容を元に  ファクトリビーン(RootBeanDefinition)や、他のビーンとの関連等を生成・生成されたビーン等をapplicationContextに登録する。 ※"applicationContext.registerBeanDefinition()"する

Page 19: GrailsでSpringをGroovyにしよう!

少し歴史など。applicationContext.xmlの内容ヒストリー

grailsApplicationgrailsResourceHoldercharacterEncodingFilter

0.1

pluginMetaManager

0.6 -> 現在

grailsResourceLoader

domainInjector

0.3

injectionOperationpluginManager

0.4 0.4.2-0.5.6

grailsConfigurator

BeanBuilder実装ユーザ拡張可能な、Plugin実装

内部的なPlugin実装

0.2

Page 20: GrailsでSpringをGroovyにしよう!

Grailsでのビーン生成と、BeanBuilder誕生までCoCを実現するために。0.1時代。- SpringConfigクラスで全てを行っていた。0.2-0.3.1時代。プラグインの原型が登場。この時代は、インターフェイスGrailsPluginを実装したクラスのdoWithGenericApplicationContext()の中で、RootBeanDefinitionをGenericApplicationContextにregisterBeanDefinition()してた。(大変そう!)0.4以降。ユーザ拡張可能なプラグインの実装。この時に、ビーンの追加も容易になるようにBeanBuilderってのが実装された。

Page 21: GrailsでSpringをGroovyにしよう!

簡単にまとめるとGrailsに柔軟な拡張性を実装 0.4からのGrailsプラグイン深い所:ビーン生成などは、0.2からの仕組みだと敷居が高くて大変だね!ぢゃあ、ビーンも解りやすくぐるーびぃーに!DSLに!BeanBuilder誕生!

Page 22: GrailsでSpringをGroovyにしよう!

BeanBuilder実装クラス:grails.spring.BeanBuilder

ApplicationContextを構築するためのDSL(Domain Specific Language)です。直感的でわかりやすくSpringビーンを定義できます。Groovyプログラムを使用して、動的にビーンを定義できます。Grailsアプリケーション以外でも使用できるように設計されています。

Page 23: GrailsでSpringをGroovyにしよう!

BeanBuiler:単独での使い方Grailsアプリケーション以外でも使用できるように設計されているので。

import org.springframework.context.ApplicationContext import grails.spring.BeanBuilder // BeanBuilderの生成

def builder = new BeanBuilder() builder.beans { // ここに定義を書く!} // ApplicationContextの生成

ApplicationContext ctx = builder.createApplicationContext()

Page 24: GrailsでSpringをGroovyにしよう!

BeanBuiler基本書式基本!

someBean(MySomeBean,"引数1",2 ,[3]){bean-> bean.singleton = false bean.factoryMethod = "getInstance" fieldOne = "JGGUG" anotherBean = ref("anotherBean",true)}

idクラス名 引数達

ビーン構成用インスタンス AbstractBeanDefinition

<bean . . . factoryMethod="getInstance"/> などのアトリビュートが定義

プロパティ定義

ビーン参照

Page 25: GrailsでSpringをGroovyにしよう!

クロージャの最初の引数は AbstractBeanDefinition

org.springframework.beans.factory.support.

AbstractBeanDefinition   → ビーン構成用インスタンス    <bean>のdestroy-method等のアトリビュート設定方法“-”をCamelCaseにする。Ex. destroy-method → destroyMethod

Page 26: GrailsでSpringをGroovyにしよう!

■Factoryメソッドの使用例

withFactoryMethod(BeanWithFactoryMethod){bean-> bean.factoryMethod = "getInstance" bean.scope = "prototype" person = "tyama"}

■Bean定義の戻り値はビーン構成用インスタンスなので、戻り値の変数に指定もできます。def somebean = withFactoryMethod(BeanWithFactoryMethod){ person = "tyama"}somebean.factoryMethod = "getInstance"somebean.scope = "prototype"

ビーン構成用インスタンス AbstractBeanDefinition

ビーン構成用インスタンス AbstractBeanDefinition

ファクトリビーン

Page 27: GrailsでSpringをGroovyにしよう!

ビーンスコープビーンスコープ - 基本は全てシングルトンです。prototypeflashflowconversationsessionsingleton

withFactoryMethod(BeanWithFactoryMethod){bean-> bean.factoryMethod = "getInstance" bean.scope = "prototype" person = "tyama"}

スコープ

Page 28: GrailsでSpringをGroovyにしよう!

ビーンの参照ApplicationContextで管理されている他のビーンへの参照xml定義での <ref bean="anotherBean"/>

ref("anotherBean") と書きます。

ref("anotherBean",true) と指定すると

親ApplicationContextのみを参照します。

Page 29: GrailsでSpringをGroovyにしよう!

■ビーンの参照beanA(BeanA){ name="bean a"}

■ref("...")で指定するbeanB(BeanB){ name="bean b" parent=ref("beanA")}

■ref("...")は、省略可能beanBB(BeanB){ name="bean b" parent=beanA}

■ref("...",true)第2引数にtrueを指定して親ApplicationContext内のみを参照beanBParent(BeanB){ name="bean b" parent= ref("beanAParent",true)}

Page 30: GrailsでSpringをGroovyにしよう!

Anonymous Inner Beans匿名インナービーン

exampleInner(ExampleBean2){ bean = {ExampleBean b -> name="My First Inner Bean" num=24 }}

■Factory Beanを使った例exampleInnerBeanFactory(ExapleBeanFactory)exampleInnerUntyped(ExampleBean2){ bean = {bean-> bean.factoryBean = "exampleInnerBeanFactory" bean.factoryMethod = "newInstance" name="example BeanFactory" num=24 }}

Page 31: GrailsでSpringをGroovyにしよう!

Beanの継承、抽象ビーン<bean id="exampleAbstractBeanNoClass" abstract="true"> <property name="name" value="abstract bean"/> <property name="num" value="20"/></bean><bean id="exampleNoCls" parent="exampleAbstractBeanNoClass" class="ExampleBean"> <property name="name" value="My First Bean"/></bean>

<bean id="exampleAbstractBeanWiCn" abstract="true" class="ExampleBean"> <property name="name" value="abstract bean"/> <property name="num" value="23"/></bean><bean id="exampleWiCn" parent="exampleAbstractBeanWiCn"> <property name="name" value="My First Bean"/></bean>

Page 32: GrailsでSpringをGroovyにしよう!

Beanの継承、抽象ビーンexampleAbstractBeanNoClass { name="abstract bean" num = 20}

(SomeClass)クラスの指定を無くす

exampleNoCls(ExampleBean){ bean -> bean.parent = exampleAbstractBeanNoClass name = "My First Bean"} bean.parentに指定する。

exampleAbstractBeanWiCn(ExampleBean){ bean -> bean.'abstract' = true name="abstract bean" num = 23}

bean.‘abstract’=trueを指定

Page 33: GrailsでSpringをGroovyにしよう!

動かしてみるGrails徹底入門10章を参考に!Gantは1.6.1 Binary, standalone installationを使用執筆時と一部仕様が変わっているので修正。build.gantの中の Ant → ant に変更。libの中身を変更commons-logging-1.1.jargrails-bootstrap-1.1.1.jargrails-spring-1.1.1.jargroovy-all-1.6.3.jarspring-2.5.6.jar デモ

Page 34: GrailsでSpringをGroovyにしよう!

BeanBuilderの

利用方法はおさえたので

Page 35: GrailsでSpringをGroovyにしよう!

GrailsでSpringビーンをGroovyに使う!

Page 36: GrailsでSpringをGroovyにしよう!

GrailsでSpringビーンをGroovyに使う!GrailsアプリケーションにSpringビーンを追加。正しい方法は3つresources.xmlに記述。resources.groovyにBeanBuilderで記述。Grailsプラグインにしてしまう。

Grailsのプロジェクト内で定義されたビーンを使うにはdef someBean と宣言するだけでOK.

Page 37: GrailsでSpringをGroovyにしよう!

resources.xmlgrails-app/conf/spring/resources.xmlにxmlでのビーン定義をそのまま書く。

デモ

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans> <bean id="exampleBean" class="bean.ExampleBean"> <constructor-arg value="hello exampleBean"/> <property name="name" value="My First Bean" /> <property name="num" value="19" /> </bean></beans>

package bean

class ExampleBean { def name def num ExampleBean(){} ExampleBean(String arg){println arg} String toString(){ "ExamplBean: $name $num" }}

Page 38: GrailsでSpringをGroovyにしよう!

resources.groovygrails-app/conf/spring/resources.groovyにBeanBuilderで記述。

デモ

package bean

class ExampleBean { def name def num ExampleBean(){} ExampleBean(String arg){println arg} String toString(){ "ExamplBean: $name $num" }}

beans = { exampleBean(ExampleBean,"hello exampleBean"){ name = "My First Bean" num = 19 } }

Page 39: GrailsでSpringをGroovyにしよう!

実装変更に使えるgrails-app/conf/spring/resources.groovy( or xml)で同名称(id)のビーンが追加された場合は、内容が上書きされます。例えば、既に定義されている “dataSource”ビーンの実装クラスを変えて定義し直したい場合。

dataSource(com.mchange.v2.c3p0.ComboPooledDataSource) { bean -> bean.destroyMethod = "close" driverClass = "org.hsqldb.jdbcDriver" jdbcUrl="jdbc:hsqldb:hsql://localhost:9001" user="sa" password=""}

定義したIDが同名のビーン内容が上書きされる

ここを変えてみた

Page 40: GrailsでSpringをGroovyにしよう!

GrailsプラグインでdoWithSpring再利用しちゃいましょう!

class JggugBeanGrailsPlugin { // the plugin version def version = "0.1".... def doWithSpring = { // TODO Implement runtime spring config (optional) exampleBean3(bean.ExamplePluginBean,"hello plugin exampleBean3"){ name = "My 3rd Bean" num = 100 } }....}

プラグインの細かい話はJGGUGの勉強会「G*」で!

Page 41: GrailsでSpringをGroovyにしよう!

SpringでGrailsを

使ってGroovyに!

Page 42: GrailsでSpringをGroovyにしよう!

applicationContext.groovy!?Grailsのソースリポジトリにコッソリ!?置いてある。grails-sample/standalone-beanbuilder 若干古いです。内容<context-param>のcontextConfigLocationに/WEB-INF/applicationContext.groovyを指定<context-param>のcontextClassにGrailsWebApplicationContextを指定あとはビーンビルダで定義するだけ。

ソースの中を見てみましょう

Page 43: GrailsでSpringをGroovyにしよう!

GrailsのGORMを使う!スタンドアロンでGORMが使用可能!Spring MVCでのサンプル、GRAILS_HOME/samples/petclinic-mvcを参照applicationContext.xmlにデータソースと、<gorm:sessionFactory/>の定義。

<gorm:sessionFactory base-package="org.grails.samples" data-source-ref="dataSource" message-source-ref="messageSource"><property name="hibernateProperties"><util:map><entry key="hibernate.hbm2ddl.auto" value="update"/>

</util:map></property>

</gorm:sessionFactory>

import

grail

s.pers

istenc

e.Enti

ty

@Entit

y

class

Person

{

String

name

...

}

Person

.groov

y

Page 44: GrailsでSpringをGroovyにしよう!

まとめAnnotationがあるぢゃないか!? (これは言わない!)BeanBuilderを使うとGrails → Springビーン利用は簡単ですよ。そして柔軟(ダイナミックだし)なので、いろいろSpringビーンの活用幅がひろがりそう。単独で動作するので、単純なビーンのテストとかに使える?

Grailsから派生したGORMSpring → Grailsのコンポーネント利用Springの内部もぐるーびぃーになる。みなさんの実運用でどうなのか解りませんが・・Grailsでドメイン設計して、ほぼ,そのままSpringで利用可能?

Page 45: GrailsでSpringをGroovyにしよう!

将来!?次期バージョンでどうなる?現在のGrailsでは、Spring 2.5.6なので、3.0に更新したらどうなっていくのか!?Grails-1.2から、Spring-3になるそうです。Graemeさんがtwitterで、いろいろつぶやいてました。

Page 46: GrailsでSpringをGroovyにしよう!

Q&Aお手柔らかに、お願いします。(T.T)濃い話しはNGで・・・

参考資料Grails徹底入門The Definitive Guide to Grails 2ndGrails-0.1~1.2のソースコード

Page 47: GrailsでSpringをGroovyにしよう!

Thank You!合同勉強会、またやりたいですね。JSUGの勉強会も参加してみたいです!

みなさまの、

  JGGUGへの参加

    お待ちしています。