Springbootで非同期処理はとっても簡単


Springbootだと非同期処理が簡単なので紹介

# ソース
```java:SpringboottestApplication.java
package net.zantetu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class SpringboottestApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringboottestApplication.class, args);
	}
}
```
起動クラスに@EnableAsyncを設定


```java:AsyncService.java
package net.zantetu.service;

import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {

	private static final Log log = LogFactory.getLog(AsyncService.class);

	public void sync(){
		log.info("service start.");
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {}
		log.info("service end.");
	}

	@Async
	public void async(){
		log.info("service start.");
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {}
		log.info("service end.");
	}

}
```
非同期処理したいメソッドに@Asyncをつける
基本これでおしまい
比較用に中身一緒のメソッドsync、asyncを作ってみる

```java:AsyncController
package net.zantetu.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import net.zantetu.service.AsyncService;

@Controller
public class AsyncController {

	private static final Log log = LogFactory.getLog(AsyncController.class);

	@Autowired
	private AsyncService asyncService;

	@RequestMapping("/sync")
	public String sync(Model model){
		log.info("controller start.");
		asyncService.sync();
		log.info("controller end.");
		return "hello";
	}

	@RequestMapping("/async")
	public String async(Model model){
		log.info("controller start.");
		asyncService.async();
		log.info("controller end.");
		return "hello";
	}

}

```
コントローラーでも同じくsync、asyncを用意してみる

```txt:syncの実行結果
2016-05-17 18:47:25.555  INFO 11560 --- [nio-8080-exec-1] net.zantetu.controller.AsyncController   : controller start.
2016-05-17 18:47:25.604  INFO 11560 --- [nio-8080-exec-1] net.zantetu.service.AsyncService         : service start.
2016-05-17 18:47:30.609  INFO 11560 --- [nio-8080-exec-1] net.zantetu.service.AsyncService         : service end.
2016-05-17 18:47:30.609  INFO 11560 --- [nio-8080-exec-1] net.zantetu.controller.AsyncController   : controller end.
```

```txt:asyncの実行結果
2016-05-17 18:48:09.982  INFO 11560 --- [nio-8080-exec-2] net.zantetu.controller.AsyncController   : controller start.
2016-05-17 18:48:09.992  INFO 11560 --- [nio-8080-exec-2] net.zantetu.controller.AsyncController   : controller end.
2016-05-17 18:48:09.993  INFO 11560 --- [cTaskExecutor-1] net.zantetu.service.AsyncService         : service start.
2016-05-17 18:48:14.994  INFO 11560 --- [cTaskExecutor-1] net.zantetu.service.AsyncService         : service end.
```
ちょっとわかりにくいけどスレッド名とかみれば非同期で動いているのがわかる。
簡単。

# まとめ
起動クラスに@EnableAsyncを設定して
非同期で動かしたいサービスのメソッドに@Asyncをつけるだけで非同期処理ができる。便利。