Spring Boot CLIを使うと、Groovyスクリプトで簡単にSpring Bootアプリケーションを書くことができます。
http://d.hatena.ne.jp/Kazuhira/20160214/1455460595
まあ、小さなスクリプト程度で済むものであれば、これでもいいかなという気もしますね。
Spring Boot CLIは、Groovyスクリプト中に書かれたクラスなどを見て、実行時の構成を自動的に決定します。例えば、
@Controller、@RestController、@EnableWebMvcがあると、Spring MVCが有効になります。
https://github.com/spring-projects/spring-boot/blob/v1.5.3.RELEASE/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java
このあたりのパッケージを見ると、スクリプト中になにを書くと、なにが有効になるかは確認することができます。
https://github.com/spring-projects/spring-boot/tree/v1.5.3.RELEASE/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure
お試し的にちょっとしたSpring MVCのアプリケーションを書いたりする時には、けっこう便利です。
ところで、単純なコンソールアプリケーションを作るにはどうしたらいいのでしょうか?
Spring Batch用のものはありますが、ちょっとそこまで要らない…みたいな場合。
https://github.com/spring-projects/spring-boot/blob/v1.5.3.RELEASE/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java
で、どうしたらいいかですが、CommandLineRunnerを実装したクラスを作成して置いておくといいのではないでしょうかと。
試しに、jsoupを使った簡単なサンプルを書いてみましょう。
Spring Boot CLIのインストール
まずは、Spring Boot CLIをインストールします。sdkmanはインストール済みとします。
Home - SDKMAN! the Software Development Kit Manager
Spring Boot CLIのインストールは、こちらのコマンドで実行します。
$ sdk install springboot
これで、「spring」コマンドが使えるようになります。
$ spring --version
Spring CLI v1.5.3.RELEASE
スクリプトを書く
それでは、サンプルのスクリプトを書いてみます。
hello-jsoup.groovy
@Grab('org.jsoup:jsoup:1.10.2') import org.jsoup.Jsoup class Runner implements CommandLineRunner { @Override public void run(String... args) { println("===== ${args[0]} =====") def doc = Jsoup.connect('https://jsoup.org/').get() def h1 = doc.select('h1') assert h1.first().text() == 'jsoup: Java HTML Parser' println("get text => ${h1.first().text()}") } }
Grapesでjsoupを依存関係に引き込み、それからCommandLineRunnerインターフェースを実装したクラスを作成しました。
あとは実行するだけです。コマンドライン引数を渡す場合は、「--」の後に指定します。
$ spring run hello-jsoup.groovy -- 'Hello World'
結果。
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.3.RELEASE) 2017-06-04 21:09:40.210 INFO 24650 --- [ runner-0] o.s.boot.SpringApplication : Starting application on ikaruga-ubuntu with PID 24650 (started by kazuhira in /home/kazuhira/study/groovy/clover/spring-boot-cli) 2017-06-04 21:09:40.215 INFO 24650 --- [ runner-0] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default 2017-06-04 21:09:40.714 INFO 24650 --- [ runner-0] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1e7557c6: startup date [Sun Jun 04 21:09:40 JST 2017]; root of context hierarchy 2017-06-04 21:09:41.543 INFO 24650 --- [ runner-0] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup ===== Hello World ===== get text => jsoup: Java HTML Parser 2017-06-04 21:09:42.939 INFO 24650 --- [ runner-0] o.s.boot.SpringApplication : Started application in 3.182 seconds (JVM running for 4.996) 2017-06-04 21:09:42.944 INFO 24650 --- [ Thread-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1e7557c6: startup date [Sun Jun 04 21:09:40 JST 2017]; root of context hierarchy 2017-06-04 21:09:42.954 INFO 24650 --- [ Thread-3] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
それぞれ、コマンドライン引数とjsoupを動かした結果が確認できます。
===== Hello World ===== get text => jsoup: Java HTML Parser
簡単なアプリケーションは、これで作れそうですね。
これが動作するのは、SpringApplicationへの依存関係がなければ「spring-boot-starter」を依存関係に追加し、
CommandLineRunnerを含むいくつかのクラスをimportするからみたいですね。
https://github.com/spring-projects/spring-boot/blob/v1.5.3.RELEASE/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java#L40-L44
Uber JARにする
ついでに、Uber JARにして実行時にはjavaコマンドがあればよいようにしましょう。
「spring jar」コマンドで、GroovyスクリプトをJARファイルにできます。
$ spring jar hello-jsoup.jar hello-jsoup.groovy
JARファイルの中には、Spring FrameworkやSpring Boot、そして自分で追加したjsoupなどが入っています。
JARファイルは、javaコマンドで実行できます。
$ java -jar hello-jsoup.jar 'Hello World'
簡単なアプリケーションなら、これでJARファイルにして実行してもよいかも?
※一応、複数Groovyファイルの実行や、複数GroovyファイルをまとめてUber JARにすることも可能みたいです
Applications with multiple source files
Packaging your application
蛇足
こう見ると、「CommandLineRunner要らないのでは?」とか「そのまま書きたいことをスクリプトに書いておけば良くない?」とか
思うかもしれませんが、そうはいかないみたいです。
例えば、先ほどのスクリプトをこういう形に修正すると
hello-jsoup.groovy
@Grab('org.jsoup:jsoup:1.10.2') import org.jsoup.Jsoup println("===== ${args[0]} =====") def doc = Jsoup.connect('https://jsoup.org/').get() def h1 = doc.select('h1') assert h1.first().text() == 'jsoup: Java HTML Parser' println("get text => ${h1.first().text()}")
動作が変わって、実装した部分がキレイに無視されます。
あと、Closureを定義してCommandLineRunnerにキャストする方法もアウトです。
def runner = { args -> println(args) } as CommandLineRunner
あくまでクラスとしての定義が必要みたいです。