Spring Loadedを使うとSpringアプリでHot Reloadingが可能です!
maven-spring-boot-pluginと組み合わせてサクサクWebアプリ開発方法を紹介します。
雛形プロジェクト作成
とりあえず汎用的にmaven-archetype-quickstartからプロジェクトをつくります。
$ mvn -B archetype:generate -DgroupId=com.example -DartifactId=hajiboot -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart
$ cd hajiboot
pom.xmlの修正
以下のようにspring-bootのdependencyとplugin(+spring loaded)の設定を追加します。
(2014/06/03時点での最新の安定版1.0.2.RELEASE
だとWindows環境でこの先の作業中に問題が発生したので1.1.0.RC1
で説明します。1.1.0.RELEASE
がリリースされたら修正します。→2014/06/12 1.1.1.RELEASE版に修正)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>hajiboot</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hajiboot</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
spring-boot-starter-test
なくてもいいけど、archetypeでTestのゴミが出力されるのでコンパイルエラーにならんように追加しておく。(どうせテストコード書くしね)
Java8入れていない人は1.8
のところを1.7
に変えておいてください。
App.java修正
アプリケーションのコードをsrc/main/java/com/example/App.javaに書きます。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@EnableAutoConfiguration
public class App {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
短いですね。
実行!
spring-loadedの制約で (2014/06/12削除: 1.1.0.RELEASEからいらなくなった?)MAVEN_OPTS=-noverify
の設定が必要。
$ mvn spring-boot:run
動いた! -> http://localhost:8080
Hot Reload!
ここからが本番。mvn spring-boot:run
を立ち上げっぱなしで、コードを修正しましょう。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@EnableAutoConfiguration
public class App {
@RequestMapping("/")
String home() {
return "Hello Spring Boot!";
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
文字列を変えました。
コンパイルすると、
2014-06-03 23:35:42.443 INFO 19756 --- [Loader@3db88bb9] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto java.lang.String com.example.App.home()
というログが・・・!(IntelliJ IDEAだと、右クリック→Compile 'App.java'が必要?) IDEがない人はmvn compile
でもOK。
ブラウザをリロードすると、
更新された!
次に以下のメソッドを追加してみましょう。
@RequestMapping("hello")
String hello(@RequestParam("name") String name) {
return "Hello " + name + "!";
}
コンパイルすると、
2014-06-04 08:14:40.249 INFO 4036 --- [Loader@58644d46] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto java.lang.String com.example.App.hello(java.lang.String)
ロードされました。
http://localhost:8080/hello?name=making にアクセスすると・・・
いけました。
Spring Bootと直接関係ない(Spring MVCの話)けど、日本語で出力したいなら
@RequestMapping(value = "hello", produces = "text/plain;charset=utf-8")
String hello(@RequestParam("name") String name) {
return "こんにちは " + name + "!";
}
でOK。この変更も即反映。
Spring Boot + Spring Loadedな開発良さげですね。
(実際のところ、Spring LoadedでどこまでHot Reloadに耐えうるか未検証なので、これから試していきます・・・)
2014-06-05追記
- 現状、起動中にインジェクション対象フィールドを増やしてもインジェクションされないみたい・・・
ちなみに、このへん含めたSpring Bootの入門書を執筆中です。
2ヶ月くらいで書ききる目標なので、Spring Bootに期待している方は少々お待ちください!