---
title: Spring BootとSpring LoadedでサクサクHot Reloading Java Webアプリ開発 springboot
tags: ["Java", "Spring", "Spring Boot"]
categories: ["Programming", "Java", "org", "springframework", "boot"]
date: 2014-06-03T06:02:56Z
updated: 2014-06-11T15:25:25Z
---

[Spring Loaded][1]を使うと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の制約で`MAVEN_OPTS=-noverify`の設定が必要。~~ (2014/06/12削除: 1.1.0.RELEASEからいらなくなった？)

    $ mvn spring-boot:run

動いた！ -> http://localhost:8080

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/4d25990f-1df6-1f76-04f1-de50729a380d.png)

### 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。

ブラウザをリロードすると、

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/4d25990f-1df6-1f76-04f1-de50729a380d.png)

更新された！

次に以下のメソッドを追加してみましょう。


    @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 にアクセスすると・・・

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/bb594bdc-44c0-4742-b084-68ce5d05406f.png)

いけました。

Spring Bootと直接関係ない(Spring MVCの話)けど、日本語で出力したいなら

    @RequestMapping(value = "hello", produces = "text/plain;charset=utf-8")
    String hello(@RequestParam("name") String name) {
        return "こんにちは " + name + "!";
    }

でOK。この変更も即反映。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/a1f8df78-ed5e-4499-7b3b-0fc640fe7841.png)

Spring Boot + Spring Loadedな開発良さげですね。

(実際のところ、Spring LoadedでどこまでHot Reloadに耐えうるか未検証なので、これから試していきます・・・)


----
2014-06-05追記

* 現状、起動中にインジェクション対象フィールドを増やしてもインジェクションされないみたい・・・

----

ちなみに、このへん含めたSpring Bootの入門書を執筆中です。

2ヶ月くらいで書ききる目標なので、Spring Bootに期待している方は少々お待ちください！


  [1]: https://github.com/spring-projects/spring-loaded
