Skip to content

Instantly share code, notes, and snippets.

@krrrr38
Last active April 29, 2018 10:40
Show Gist options
  • Save krrrr38/e629f6057810f913a4a34b1e259b0869 to your computer and use it in GitHub Desktop.
Save krrrr38/e629f6057810f913a4a34b1e259b0869 to your computer and use it in GitHub Desktop.
SpringOne Platform 2017

SpringOne Platform2017報告として、以下のことについて話します (QA入れて40分~ぐらいある気がする)

  • カンファレンスの観光的要素: 5分
  • 聞いたセッションの話: 大体後述するのに集約されるのでさっと5分
  • セッションを踏まえ、主要なトピックについて、社内で(将来的に)使える感じの便利情報として: 30分
    • Spring Framework 5.0 / Spring Boot 2
    • reactive-streams / reactor / spring-webflux
    • Micrometer

観光的な要素

  • サンフランシスコ事情
  • SpringOnePlatform的な
    • Pivotal カクテルセッション行ったよ

聞いたセッションの話

  • 面白かったやつ
    • What's new Spring Boot2 (後でまとめて話す)
    • spring framework 5.0 on JDK 8 & 9 (後でまとめて話す)
    • Project Reactor: Now & Tommorrow (後でまとめて話す)
    • Spring Framework 5: Hidden Gems (後でまとめて話す)
    • Observability with Micrometer Metrics (後でまとめて話す)
    • 55 New Features in JDK 9 (資料まとまってるので見てね^^)
  • そこまで面白くなかったやつ
    • Reactor in Action (基礎)
    • New in Spring Framework 5.0: Function WebFramework: RouterFunctionsの基礎
  • main stage: 軽く
    • PCF2.0 (社内じゃ使わん)
    • Spring Boot 2.0 demo
    • Boeingの人/HCSCの人/Accentureの人/Air Forceの人
    • Distribution System話
    • Googleの人: service mesh~
  • 全体の様子
    • live coding多かった
      • 観客が直接声かけて助けたりしてるの良かった
    • 最大10並列あって、あたりはずれ選ぶの難しい
    • 大体発表時に自分 or projectのtwitter account紹介して、なんかあったら聞いてねって言ってたの良かった

セッションを踏まえて、主要なトピックについて、社内で使える感じの便利情報をがっつり: 30分

spring framework 5.0 & spring-boot 2.0

  • Java8+, tomcat8+, thymeleaf3, hibernate5.2
  • reactive spring
    • reactive stack: netty, servlet3.1, undertow, reactive streams, spring webflux
    • reactive streams: reactor (Mono, Flux)
  • functional apis: RouterFunctions
  • kotlin support
  • anigif banner
  • environment variable
  • MY_VAR_1_2=b => my.var[1][2] = "b"
  • java.time integration
  • Duration: "1s", "2m", "5d"
  • bootRepackage -> bootJar/bootWar
  • actuator improvements: https://spring.io/blog/2017/08/22/introducing-actuator-endpoints-in-spring-boot-2-0
    • endpoint annotation: @Endpoint("example"), @WebEndpoint, @JmxEndpoint
    • tech independent operations: @ReadOperation(String read()), @WriteOperation(void write(String[] args)), @DeleteOperation
    • tech specific extensions: @EndpointWebExtension, @EndpointJmxExtension
  • spring security improvements: 結構色々してる?
    • webflux対応
    • No ordering issues with WebSecurityConfigurerAdapter
    • web actuator endpoints have consistent behavior
  • webflux: reactor <--
  • micro meter metrics <--
  • spring-jcl: custom commons loggin bridge
    • no custom bridges and no custom excludes in application poms
  • build-time components indexer
    • build時にcomponennt scan 対象を META-INFO/spring.components のファイルにまとめて、起動速度を上げる
  • ListenableFuture から CompletableFuture に変換する .completable() の追加
  • Data Class Binding: ...TODO
    • Spring data binding can work with immutable classes now
    • Property names matched against constructor parameter names
    • explicit property names via @ConstructorProperties or simply inferred from class bytecode(-parameters or -debug)
    • Perfect match: Kotlin data classes and Lombok data classes

reactive-stream / reactor / spring-webflux

reactive-stream

http://www.reactive-streams.org/

ノンブロッキングな排圧制御を持つ非同期ストリーム処理の標準化

データのinterfaceのみ提供して、皆で以下のinterfaceをまもったapiを提供していこうねっていう取り決め的なsomething

org.reaactivestreams:reactive-streams には以下のinterfaceしか無い

  • Pulisher: データをsubscriberに渡すやつ
    • void subscribe(Subscriber<? super T> s)
  • Subscriber: Publisherのデータを購読するやつ
    • void onNext(T t);
    • void onError(Throwable t);
    • void onComplete();
    • void onSubscribe(Subscription s);
  • Subscription
    • 1:1対応されているpub/subに対するinterface (cancelとか出来る)
  • Processor<T, R> extends Subscriber, Publisher
    • データの処理をして中継したりするやつ

何が嬉しいの?

  • ノンブロッキングな処理を並行に処理出来る、ちゃんとcpu使える
  • back pressure
  • お互いに共通のmethodがあるので、かんたんにadapterを提供出来る
    • e.g. JdkFlowAdapter: reactor -> Java Flow
for (int i = 1; i <= 1000; i++) {
  handleBody(blockingHttpGet())
}
Flux.range(1, 1000)
    .flatMap(i -> reactiveHttpCall())
    .subscribe(this::handleBody)

実装してるやつ一例

  • reactor: springで使われてる
  • RxJava: reactive
  • akka-stream: lightbend
  • Java9: java.util.concurrent.Flow <- !!
    • Flow.Publisher
    • Flow.Subscriber

javaのweb application serverの場合?

  • 基本的にresponse書き込みSubscriberが用意されているので、来たリクエストに対してresponseをpublishするPublisher(e.g. Mono/Flux)を実装してあげたら良い
    • e.g. ServletHttpHandlerAdapter.serviceとかにあるよ
  • SSEとかFluxを使うと簡単に出来て面白いよ

reactor

(Project Reactor: Now & Tomorrow)

reactorの提供API

reactive-streamの実装の1つで、spring-webfluxで使われている

  • Mono implements Publisher
    • 0個か1子のデータをpublishする、特別なPublisher
  • Flux implements Publisher
    • 0個以上のデータをpublishする、基本的なPublisher

reactor 3.1 (latest)

  • refactoring
  • reactor x kotlin
  • Scannable
    • 階層的にデータを辿れるVisitorパターンなどに利用出来るもの
  • Tagging, Naming
    • Flux.range(1, 10).name("name").tag("foo", "bar")
  • Hooks
    • e.g. tagに"METRICS"って名前があるやつのメトリクスを取得するとか...
  • Immutable Context
    • event-drivenで処理する際に利用するimmutableなContextを内部で持つ

より詳細は: https://spring.io/blog/2017/09/28/reactor-bismuth-is-out

Ecosystem

  • reactor-netty -reactor- kafka
  • reactor-rabbitmq
  • reactor-addons
    • retry support
    • Math
    • Cache (CacheMono/CacheFlux)

Comunity

  • spring
  • reactive-gRPC from salesforce
  • lettuce
  • reactor-scala-extensions

reactor tomorrow

  • より高度なエラーハンドリング
    • ASIS: Flux.range(0,3).flatMap(v -> Mono.just(v).map(i -> 100 / i).doOnError(...).doErrorResume(Mono.Empty()))
    • TOBE?: Flux.range(0,3).map(i -> 100 / i).errorStrategyContinue().filter(i -> 100 / i > 4);
  • 監視系
    • Migrometer integration
    • Sleuth / Zipkin integration
  • reactor-netty
    • initial user guide
    • http2 support
  • java9
  • rsocket
  • asynchronous db adapter?

spring-webflux

  • "web"flux: reactive-streamの機能をserver/clientの繋ぎ込みの部分で使えるようにするやつ
    • server
@GetMapping("ok")
Mono<String> ok() {
	return Mono.just("ok");
}
  • client
Mono<Person> bodyMono = webClient.get()
     .uri("/persons/1")
     .accept(MediaType.APPLICATION_JSON)
     .retrieve()
     .bodyToMono(Person.class);

non-blocking for web application engineer

Webアプリケーション側のエンジニアとして、2つの観点から必要性を考えます

  1. application layer で non-blocing を使う必要性
  2. server で non-blocking(async) を使う必要性
application layer で non-blocing を使う必要性

正直な所、これは大凡便利

  • POS
    • 並列に投げたいとこが出たら簡単に並列に処理出来る
    • コード綺麗になる
    • back pressure
  • NEG
    • 学習コスト少し (基本的にblockしてはならないなど)
server で non-blocking(async) を使う必要性

これは必要に応じて

request threadで大量のリクエストを裁こうとするとコストが高いので、きちんとendpointに対して一貫してnon-blockingな処理が出来てるなら、きちんとcpu使い切れるようになります

https://engineering.linecorp.com/ja/blog/detail/213 も読んでね

QA

  • JDBCはblockする処理だけどどうするの?
    • AsyncJDBCを待つ
    • 専用のThreadPool用意する
  • blockしてる箇所とかどうやって調べるの?
    • flight recorderが便利らしいよ
    • thread専有してる箇所とか探せば良い

spring-webfluxをもう少し

良く言われてるのはこれ

@GetMapping("ok")
Mono<String> ok() {
	return Mono.just("ok");
}

実はこれでもいい (Mono/Flux implements Publisher)

@GetMapping("ok")
Publisher<String> ok() {
	return Mono.just("ok");
}

これも動く(が、どこかにblockingな処理がありえるので注意)

@GetMapping("ok")
String ok() {
	return "ok";
}
  • これらの変換をしているのは AbstractMessageWriterResultHandler.writeBody

    • Stringは Mono.justOrEmpty で包まれる
    • Mono/Publisher/CompletableFuture/... などは、ReactiveAdapterRegistry で変換される
  • ReactiveAdapterRegistry?

  • nettyしか使えないの?

    • servletのasync supportを有効にして、 org.springframework.http.server.reactive.TomcatHttpHandlerAdapter/JettyHttpHandlerAdapter とか使えるよ

Micrometer

Observability with Microemter Metrics

Micrometerとは?

  • Think SLF4J, but for metrics
  • メトリクスを収集して、色々な所へ飛ばせるfacade的なもの
    • JMX, Prometheus, InfluxDB, Graphite, Datadog, ...
    • IMON?
  • springへの依存は無いので、どこでも使える e.g. armeria

dropwizard-metricsと何が違うの?

  • タグがある
    • name + tag により、それらの概念を利用してるデータリポジトリとの統合が簡単に

使い方: 依存

  • spring-boot2 Micrometer is autoconfigurered by Actuator
dependencies {
 compile 'org.springframework.boot:spring-boot-starter-actuator'
 // pick any number of backing stores
 runtime 'io.micrometer:micrometer-registry-prometheus'
 runtime 'io.micrometer:micrometer-registry-jmx'
}
  • boot1
dependencies {
 compile 'org.springframework.boot:spring-boot-starter-actuator'

 runtime 'io.micrometer:microemter-spring-legacy:1.0.0-rc.4'

 // pick any number of backing stores
 runtime 'io.micrometer:micrometer-registry-prometheus:1.0.0-rc.4'
 runtime 'io.micrometer:micrometer-registry-jmx:1.0.0-rc.4'
}

使い方: 基本

  • Counter / Timer / Gauge
CompositeMeterRegistry registry = new CompositeMeterRegistry();
regitstry.add(SampleRegistries.jmx()); // jmx に metrics を吐く
regitstry.add(SampleRegistries.prometheus()) // prometheus用のhttp serverが立つ

// registryから作るapi
Counter counter = registry.counter(name, ...tags);
// builder的に作るapi
Counter counter = Counter.builder(name).tag(...).baseUnit().registry(registry);

// Counterはデータを inc/dec させるもの
counter.increment();

使い方: FunctionCounter/FunctionTimer

任意のobjectのstateから値を取得する事が出来る

AtomicInteger n = new AtomicInteger(); // state
FunctionCounter.builder(name, n, AtomicInteger::get).register(registry);

spring boot2話

  • spring-boot2の場合はactuatorのautoconfigurationがあるので、設定で色々変えれるよ
spring.metrics.filter.my.timer:
  percentilesHistogram: true // default false
  sla: 100ms
  • とあるmethodにかかる時間を測定したい
@Timed(percentiles = {0.5, 0.95, 0.999}, histgram = true)
@GetMapping(...)
public Mono<String> ok() {
  // ...
}

その他

  • jvmの基本的なメトリクス取るものはそのままついてくるよ
  • logback/tomcat/jetty/...などなどへのintegrationも本家にあるよ
  • documentちゃんとあるので、一通り読むともっと学べます

spring-boot-starter-webflux

compile('org.springframework.boot:spring-boot-starter-webflux')
r.i.n.h.s.HttpServer [reactor-http-nio-1] - [id: 0xaaee0af5, L:/0:0:0:0:0:0:0:0:8080] READ: [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496]
r.i.n.h.s.HttpServer [reactor-http-nio-1] - [id: 0xaaee0af5, L:/0:0:0:0:0:0:0:0:8080] READ COMPLETE
r.i.n.h.s.HttpServerOperations [reactor-http-nio-3] - New http connection, requesting read
r.i.n.c.ContextHandler [reactor-http-nio-3] - After pipeline DefaultChannelPipeline{(reactor.left.loggingHandler = io.netty.handler.logging.LoggingHandler), (ServerContextHandler#0 = reactor.ipc.netty.channel.ServerContextHandler), (reactor.left.httpCodec = io.netty.handler.codec.http.HttpServerCodec), (reactor.left.httpServerHandler = reactor.ipc.netty.http.server.HttpServerHandler), (reactor.right.reactiveBridge = reactor.ipc.netty.channel.ChannelOperationsHandler)}
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] REGISTERED
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] ACTIVE
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] READ: 81B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 67 65 74 20 48 54 54 50 2f 31 2e |GET /get HTTP/1.|
|00000010| 31 0d 0a 48 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f |1..Host: localho|
|00000020| 73 74 3a 38 30 38 30 0d 0a 55 73 65 72 2d 41 67 |st:8080..User-Ag|
|00000030| 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 35 34 2e 30 |ent: curl/7.54.0|
|00000040| 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 0d |..Accept: */*...|
|00000050| 0a                                              |.               |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServerOperations [reactor-http-nio-3] - Increasing pending responses, now 1
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] READ COMPLETE
r.i.n.c.ChannelOperations [reactor-http-nio-3] - [HttpServer] [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter@2808ff86
o.s.w.r.DispatcherHandler [reactor-http-nio-3] - Processing GET request for [http://localhost:8080/get]
o.s.b.a.e.w.r.WebFluxEndpointHandlerMapping [reactor-http-nio-3] - Looking up handler method for path /get
o.s.b.a.e.w.r.WebFluxEndpointHandlerMapping [reactor-http-nio-3] - Did not find handler method for [/get]
o.s.w.r.r.m.a.RequestMappingHandlerMapping [reactor-http-nio-3] - Looking up handler method for path /get
o.s.w.r.r.m.a.RequestMappingHandlerMapping [reactor-http-nio-3] - Returning handler method [public org.reactivestreams.Publisher<java.lang.String> com.krrrr38.sample.springsample.MyController.getBody()]
o.s.b.f.s.DefaultListableBeanFactory [reactor-http-nio-3] - Returning cached instance of singleton bean 'myController'
c.k.s.s.MyController [reactor-http-nio-3] - get start
r.i.n.c.ChannelOperationsHandler [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] Writing object DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 200 OK
transfer-encoding: chunked
Content-Type: text/plain;charset=UTF-8
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] WRITE: 87B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
|00000010| 0a 74 72 61 6e 73 66 65 72 2d 65 6e 63 6f 64 69 |.transfer-encodi|
|00000020| 6e 67 3a 20 63 68 75 6e 6b 65 64 0d 0a 43 6f 6e |ng: chunked..Con|
|00000030| 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f |tent-Type: text/|
|00000040| 70 6c 61 69 6e 3b 63 68 61 72 73 65 74 3d 55 54 |plain;charset=UT|
|00000050| 46 2d 38 0d 0a 0d 0a                            |F-8....         |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] FLUSH
r.i.n.c.ChannelOperationsHandler [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] Writing object FluxMap
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] WRITE: 3B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 32 0d 0a                                        |2..             |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] WRITE: 2B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 6f 6b                                           |ok              |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] WRITE: 2B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 0d 0a                                           |..              |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] FLUSH
o.s.h.s.r.ReactorServerHttpResponse [reactor-http-nio-3] - Skipping doCommit (response already committed).
o.s.h.s.r.ReactorHttpHandlerAdapter [reactor-http-nio-3] - Successfully completed request
r.i.n.h.s.HttpServerOperations [reactor-http-nio-3] - Last HTTP response frame
r.i.n.c.ChannelOperationsHandler [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] Writing object EmptyLastHttpContent
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] WRITE: 5B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 30 0d 0a 0d 0a                                  |0....           |
+--------+-------------------------------------------------+----------------+
r.i.n.h.s.HttpServerOperations [reactor-http-nio-3] - Decreasing pending responses, now 0
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] FLUSH
r.i.n.c.ChannelOperations [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] Discarding inbound content
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] USER_EVENT: [Handler Terminated]
r.i.n.c.ChannelOperationsHandler [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] Disposing context reactor.ipc.netty.channel.ServerContextHandler@2220ecd2
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:58496] READ COMPLETE
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 ! R:/0:0:0:0:0:0:0:1:58496] INACTIVE
r.i.n.h.s.HttpServer [reactor-http-nio-3] - [id: 0x967169be, L:/0:0:0:0:0:0:0:1:8080 ! R:/0:0:0:0:0:0:0:1:58496] UNREGISTERED

spring-boot-starter-web

compile('org.springframework.boot:spring-boot-starter-web')
compile('io.projectreactor:reactor-core')
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Did not find handler method for [/get]
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Returning handler method [public org.reactivestreams.Publisher<java.lang.String> com.krrrr38.sample.springsample.MyController.getBody()]
o.s.b.f.s.DefaultListableBeanFactory [http-nio-8080-exec-2] - Returning cached instance of singleton bean 'myController'
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Returning handler method [public org.reactivestreams.Publisher<java.lang.String> com.krrrr38.sample.springsample.MyController.getBody()]
o.s.b.f.s.DefaultListableBeanFactory [http-nio-8080-exec-2] - Returning cached instance of singleton bean 'myController'
o.s.b.w.s.f.OrderedRequestContextFilter [http-nio-8080-exec-2] - Bound request context to thread: org.apache.catalina.connector.RequestFacade@7e8c7d89
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/get]
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Did not find handler method for [/get]
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Returning handler method [public org.reactivestreams.Publisher<java.lang.String> com.krrrr38.sample.springsample.MyController.getBody()]
o.s.b.f.s.DefaultListableBeanFactory [http-nio-8080-exec-2] - Returning cached instance of singleton bean 'myController'
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - Last-Modified value for [/get] is: -1
c.k.s.s.MyController [http-nio-8080-exec-2] - get start
o.s.w.c.r.a.WebAsyncManager [http-nio-8080-exec-2] - Concurrent handling starting for GET [/get]
o.s.w.c.r.a.WebAsyncManager [http-nio-8080-exec-2] - Concurrent result value [ok] - dispatching request to resume processing
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - Leaving response open for concurrent processing
o.s.b.w.s.f.OrderedRequestContextFilter [http-nio-8080-exec-2] - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@7e8c7d89
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - DispatcherServlet with name 'dispatcherServlet' resumed processing GET request for [/get]
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.b.a.e.w.s.WebMvcEndpointHandlerMapping [http-nio-8080-exec-2] - Did not find handler method for [/get]
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Looking up handler method for path /get
o.s.w.s.m.m.a.RequestMappingHandlerMapping [http-nio-8080-exec-2] - Returning handler method [public org.reactivestreams.Publisher<java.lang.String> com.krrrr38.sample.springsample.MyController.getBody()]
o.s.b.f.s.DefaultListableBeanFactory [http-nio-8080-exec-2] - Returning cached instance of singleton bean 'myController'
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - Last-Modified value for [/get] is: -1
o.s.w.s.m.m.a.RequestMappingHandlerAdapter [http-nio-8080-exec-2] - Found concurrent result value [ok]
o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor [http-nio-8080-exec-2] - Written [ok] as "text/plain" using [org.springframework.http.converter.StringHttpMessageConverter@4ce14f05]
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
o.s.w.s.DispatcherServlet [http-nio-8080-exec-2] - Successfully completed request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment