Groovyでアノテーションを扱う方法
サンプル
漠然とアノテーションを使ってみても面白みが無いので、以下のようなありがちな状況を想定。
- クラスのフィールドに対して、DB上の型を定義するアノテーションを付加する。
- Userクラスを作成し、その name フィールドの値をDB上では text 形にする。(1)
- ORマッパーが、そのBeanのアノテーションを見て、DB上の型を判断。(2)
// 必要なクラスのインポート import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy // アノテーションの作成(ランタイムでも取得できるようにRetention.RUNTIMEで設定) @Retention(RetentionPolicy.RUNTIME) @interface Type { String value() } // アノテーションを使用したクラスの作成 class User { @Type("text") // (1) String name } // アノテーションを使用したクラスから、アノテーションを取得 Object annotation = User.getDeclaredField("name").getAnnotations()[0] // アノテーションの型が Type 型であることを確認 assert annotation instanceof Type // アノテーションの value() の値が "text" であることを確認。 assert ((Type)annotation).value() == "text" // (2)
Groovy からも簡単にアノテーションが使えますねー (`・ω・´)
おまけ:Groovy1.5でアノテーション定義した場合のエラー
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Script0: 6: Unknown type: ANNOTATION_DEF at line: 6 column: 1. File: Script0 @ line 6, column 1. 1 error at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:296) at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:787) at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:438) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:281) at groovy.lang.GroovyShell.parseClass(GroovyShell.java:572) at groovy.lang.GroovyShell.parse(GroovyShell.java:584) at groovy.lang.GroovyShell.parse(GroovyShell.java:564) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:542) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:484) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756) at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:778) at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:758) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170) at groovy.ui.Console$_runScriptImpl_closure5.doCall(Console.groovy:497) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:248) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:78) at groovy.ui.Console$_runScriptImpl_closure5.doCall(Console.groovy) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:248) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756) at groovy.lang.Closure.call(Closure.java:292) at groovy.lang.Closure.call(Closure.java:287) at groovy.lang.Closure.run(Closure.java:368) at java.lang.Thread.run(Thread.java:619)