2016-12-27 18 views
3

私はjava.util.concurrent.Callableを使用して、最も単純な非同期RESTコントローラを実行しようとしている:春ブーツMVCの非同期実行

@RequestMapping("/AsyncRequest") 
public Callable asyncRequest() { 
    return() -> { 
     Thread.sleep(3000); 
     return "reply"; 
    }; 
} 

は、それから私は、ブラウザでhttp://localhost/AsyncRequest 2回実行します。 最初の回答は3秒で、2回目の回答は6秒後です。 リクエストが非同期ではなく処理されているようです。 これはなぜ発生するのですか?

+0

両方の要求を処理するスレッドが同じであるように見えます。 –

+0

@Christopher Schneider、スレッドIDを確認しましたが、それらは異なっていました。 – Andrew

+0

いいえ...私はちょうど機能的に同じものを書いて、あなたの結果を再現できません。これはJava 7とPivotal tc Server 3.1.3で行われました –

答えて

2

スプリングブートの動作は、実際のバージョンと構成によって異なります。

次のような構成とコードの私の作品:

スターター

package com.stackoverflow.spring.boot.async; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.context.annotation.Import; 

@Import(WebConfig.class) 
@SpringBootApplication 
public class WebMain { 
    private final SpringApplication application; 

    public WebMain() { 
    final SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(WebMain.class); 
    application = applicationBuilder.build(); 
    } 

    public SpringApplication getApplication() { return application; } 

    public static void main(final String[] args) { 
    new WebMain().getApplication().run(args); 
    } 
} 

設定

package com.stackoverflow.spring.boot.async; 


import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; 
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 

@Configuration 
public class WebConfig extends WebMvcConfigurerAdapter implements EmbeddedServletContainerCustomizer 
{ 
    public void customize(final ConfigurableEmbeddedServletContainer container) {} 
} 

コントローラ

私はここでスリープ時間を6秒に変更し、応答にペイロードを追加しました。

package com.stackoverflow.spring.boot.async; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 

import java.util.Date; 
import java.util.concurrent.Callable; 

@Controller 
public class AsyncController { 
    @RequestMapping(path = "/AsyncRequest", method = RequestMethod.GET) 
    @ResponseBody 
    public Callable<String> asyncRequest() { 
    return() -> { 
     final long currentThread = Thread.currentThread().getId(); 
     final Date requestProcessingStarted = new Date(); 

     Thread.sleep(6000L); 

     final Date requestProcessingFinished = new Date(); 

     return String.format(
      "request: [threadId: %s, started: %s - finished: %s]" 
      , currentThread, requestProcessingStarted, requestProcessingFinished); 
    }; 
    } 
} 

のpom.xml

<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/maven-v4_0_0.xsd"> 

     <modelVersion>4.0.0</modelVersion> 

     <groupId>com.stackoverflow.spring.boot</groupId> 
     <artifactId>async</artifactId> 
     <packaging>jar</packaging> 
     <version>1.0-SNAPSHOT</version> 

     <properties> 
     <java.version>1.8</java.version> 
     <spring-boot.version>1.4.1.RELEASE</spring-boot.version> 
     </properties> 

     <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-dependencies</artifactId> 
      <version>${spring-boot.version}</version> 
      <type>pom</type> 
      <scope>import</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot</artifactId> 
      <version>${spring-boot.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
      <version>${spring-boot.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-actuator</artifactId> 
      <version>${spring-boot.version}</version> 
     </dependency> 
     </dependencies> 

     <build> 
     <plugins> 
      <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <version>3.5.1</version> 
      <inherited>true</inherited> 
      <configuration> 
       <source>${java.version}</source> 
       <target>${java.version}</target> 
      </configuration> 
      </plugin> 

      <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> 
      <version>${spring-boot.version}</version> 
      <executions> 
       <execution> 
       <goals> 
        <goal>repackage</goal> 
       </goals> 
       <configuration> 
        <classifier>exec</classifier> 
       </configuration> 
       </execution> 
      </executions> 
      </plugin> 
     </plugins> 
     </build> 

    </project> 

テスト

java -version 
java version "1.8.0_111" 
Java(TM) SE Runtime Environment (build 1.8.0_111-b14) 
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode) 

-- 
mvn spring-boot:run 
... 
-- 
# start following command from different consoles: 
curl http://localhost:8080/AsyncRequest 

結果

request: [threadId: 33, started: 15:50:28 - finished: 15:50:34] 
request: [threadId: 35, started: 15:50:29 - finished: 15:50:35] 
request: [threadId: 37, started: 15:50:30 - finished: 15:50:36] 
+1

ありがとうございます。それは私が問題を見つけるのを助けました。私の問題の理由はGoogle Chromeでした:それは同じURLの要求を最適化しました。あなたの答えでは、カールを使用しました。私もそれを使ってサーバーをテストしようとしましたが、私は正しい結果を得ました。 – Andrew