---
title: JRebel でSpring Bootアプリケーションの快適リローディング (IntelliJ IDEA編)
tags: ["IntelliJ IDEA", "JRebel", "Spring Boot"]
categories: ["Dev", "IDE", "IntelliJIDEA", "JRebel"]
date: 2015-05-17T06:54:04Z
updated: 2015-05-17T06:54:04Z
---

Javaアプリケーション実行中に動的にクラスをリロードをしてくれる[JRebel](https://zeroturnaround.com/software/jrebel/)がとても便利なので紹介します。特にSpring Bootのようなスタンドアローンアプリケーションの開発中にとても有用です。

ここではIntelliJ IDEAでセットアップします。[Eclipse](http://zeroturnaround.com/software/jrebel/quickstart/eclipse/)でも、[NetBeans](http://zeroturnaround.com/software/jrebel/quickstart/netbeans/)でも使えます。

**File > Settings**を開き、**Plugins**を選択します。
**Browse Repositories**をクリックし、**JRebel Plugin**を探し、**Install plugin**ボタンをクリックします。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/017aae52-9816-1b79-7405-684457c3e23e.png)

IntelliJ IDEAを再起動すると、**Run with JRebel**コマンドが追加されます。

次の簡単なSpring Bootを実行します。

``` java
package demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    @Bean
    CommandLineRunner foo() {
        return args -> System.out.println("hoge!");
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
```

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/b8c8d077-de7f-9f57-220d-a9298098e3dd.png)

`DemoApplication`クラスを右クリックして、**Run with JRebel "DemoApplication"**を実行しようとすると、初回はアクティベーションを求められます。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/44687792-7221-da2a-343f-ff849378234c.png)

14日間のフリートライアルを使うか、ライセンスキーを入力する必要があります。わたしは**非商用の個人利用に限り**使用できる、[myJRebel](https://my.jrebel.com/)のライセンスキーを取得したので、それを入力します。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/0c62ed3a-632e-d142-ca9e-fe8a3c30f2b2.png)

**Activate JRebel**ボタンを押せば、アクティベーションが完了します。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/34749793-44b6-de94-6919-929974c67871.png)

再度、**Run with JRebel "DemoApplication"**を実行すれば、以下のようなJRebelのログが出力されたあと、アプリケーションが起動します。

```
2015-05-17 16:00:16 JRebel: Contacting myJRebel server ..
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  #############################################################
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  JRebel Legacy Agent 6.1.3 (201504281742)
2015-05-17 16:00:18 JRebel:  (c) Copyright ZeroTurnaround AS, Estonia, Tartu.
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  Over the last 1 days JRebel prevented
2015-05-17 16:00:18 JRebel:  at least 6 redeploys/restarts saving you about 0.2 hours.
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  Licensed to Toshiaki Maki (using myJRebel).
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:18 JRebel:  #############################################################
2015-05-17 16:00:18 JRebel:  
2015-05-17 16:00:19 JRebel: Monitoring resource '/Users/maki/git/firstapp/target/classes/application.properties'.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.3.RELEASE)
...
```

アプリケーションを立ち上げたまま、以下のようにソースコードを修正します。

``` java
package demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

    @Bean
    CommandLineRunner foo() {
        return args -> System.out.println("hoge!");
    }

    @RequestMapping("/")
    String hello() {
        return "hello";
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
```

右クリックして、**Compile 'DemoApplication.java'*をクリックし、`http://localhost:8080`にアクセスすると、

```
2015-05-17 16:09:37 JRebel: Reloading class 'demo.DemoApplication'.
2015-05-17 16:09:37 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580'.
2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580'.
2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$FastClassBySpringCGLIB$$7211a142'.
2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580$$FastClassBySpringCGLIB$$54aa9091'.
2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580$$FastClassBySpringCGLIB$$54aa9091'.
2015-05-17 16:09:38 JRebel: Reconfiguring bean 'demoApplication' [demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580]
2015-05-17 16:09:38 JRebel: Reconfiguring bean 'demoApplication' [demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580]
2015-05-17 16:09:38.927  INFO 1853 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-05-17 16:09:38.928  INFO 1853 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2015-05-17 16:09:38.970  INFO 1853 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 41 ms
2015-05-17 16:09:39.000  INFO 1853 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-05-17 16:09:39.007  INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto java.lang.String demo.DemoApplication.hello()
2015-05-17 16:09:39.009  INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2015-05-17 16:09:39.009  INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
```

というように影響のあるクラスがリロードされていることがわかります。アプリケーション再起動に比べてかなり高速に動作するので、作業効率が大幅に向上すると思われます。

リロード時のGifアニメ貼っておきます。

<a href="http://recordit.co/pSFIbHnsb5"><img src="http://g.recordit.co/pSFIbHnsb5.gif" width="80%"></a>

一々、右クリックコンパイルするのは面倒なので、`Ctrl+S`に**Make Project**をマッピングさせておくと、便利です。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/57b1b978-e960-62f6-7279-3b91db0be4ec.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/81967446-9566-5435-21f5-927a308bc307.png)

ソースを修正するだけ修正したあと、`Ctrl+S`を実行し、アプリケーションにアクセスすればリロードされます。

再DIもそこそこ対応しており、Spring Loadedみたいに不安定ではないので、かなりオススメです。

気に入ったら商用ライセンスを買いましょう。お買い求めは[Samuraism](http://samuraism.com/products/zeroturnaround/jrebel)まで！
