Copyright©2017 NTT corp. All Rights Reserved.
Spring I/O 2017 報告会
ThymeleafのWebFlux対応
2017年6⽉29⽇
NTT ソフトウェアイノベーションセンタ
岩塚 卓弥
2Copyright©2017 NTT corp. All Rights Reserved.
• 名前:岩塚 卓弥
• 所属:NTT ソフトウェアイノベーションセンタ
• NTTの研究所のうちソフトウェアを専⾨に扱う
• ⾃部署ではソフトウェア⼯学を研究
• Springベースのグループ共通フレームワークの整備を担当
• Spring I/Oには2015年から3年連続参加
⾃⼰紹介
3Copyright©2017 NTT corp. All Rights Reserved.
• Getting Thymeleaf Ready for Spring 5 and
Reactive
• Daniel Fernández – Thymeleaf lead
• スライド
• https://speakerdeck.com/dfernandez/o-2017-getting-
thymeleaf-ready-for-spring-5-and-reactive
• デモ
• https://github.com/danielfernandez/reactive-matchday
今⽇の元ネタ(⼀次資料)
4Copyright©2017 NTT corp. All Rights Reserved.
• Thymeleaf 3を使⽤している
• Thymeleaf 2を使⽤している
• JSPを使⽤している
• その他のテンプレートエンジンを使っている
会場アンケート:Thymeleaf 使ってますか
5Copyright©2017 NTT corp. All Rights Reserved.
世界での利⽤状況
Spring Initializrで選択される
テンプレートエンジンのうち
75%程度がThymeleaf
Thymeleaf Freemarker Mustache
Groovy Templates Velocity
⽉間DL数は22万以上
⼀年で7万5千以上の伸び
Spring I/O 2017 Keynoteより
6Copyright©2017 NTT corp. All Rights Reserved.
Spring MVC × Thymeleaf 3 の基本形
greeting.html
実装
出⼒
7Copyright©2017 NTT corp. All Rights Reserved.
Spring MVC × Thymeleaf 3 処理概略
TemplateName
Context
Engine
Model
Template
+α
HTML
Controllerで設定したModel
(Map<String, Object>)
8Copyright©2017 NTT corp. All Rights Reserved.
Spring MVC × Thymeleaf 3 処理概略
TemplateName
Context
Engine
Model
Template
+α
HTML
Controllerから渡された
View名を解決したもの
ServletContextや
パス変数等を追加
9Copyright©2017 NTT corp. All Rights Reserved.
Spring MVC × Thymeleaf 3 処理概略
TemplateName
Context
Engine
Model
Template
+α
HTMLTemplateを取得
TemplateとContextから
HTMLを⽣成
10Copyright©2017 NTT corp. All Rights Reserved.
Spring MVC × Thymeleaf 3 処理概略
TemplateName
Context
Engine
Model
Template
+α
HTML HttpServletResponseに
書き込み
11Copyright©2017 NTT corp. All Rights Reserved.
Reactive化?
TemplateName
Context
Engine
Model
Template
+α
HTML
Blocking! Blocking!
12Copyright©2017 NTT corp. All Rights Reserved.
Reactive化?
TemplateName
Context
Engine
Model
Template
+α
HTML
Blocking! Reactive!
出⼒をPublisherに
13Copyright©2017 NTT corp. All Rights Reserved.
• FULL
• CHUNKED
• DATA-DRIVEN
Reactiveな3つの処理モード
14Copyright©2017 NTT corp. All Rights Reserved.
FULLモード
HTML
Mono<DataBuffer>Engine
ServerHttpResponseに書き込み
HTMLを⼀括⽣成して⼀括出⼒
→ 最もシンプルだがメモリ消費は⼤
15Copyright©2017 NTT corp. All Rights Reserved.
• FULL
• CHUNKED
• DATA-DRIVEN
Reactiveな3つの処理モード
16Copyright©2017 NTT corp. All Rights Reserved.
CHUNKEDモード
<!DOCTYPE html>
…
Flux<DataBuffer>Engine
ServerHttpResponseに書き込み
・・・
…
</html>
HTMLを⼀定のバイト数ごとに区切って⽣成
→ backpressureによって速度調整可能に
17Copyright©2017 NTT corp. All Rights Reserved.
• FULL
• CHUNKED
• DATA-DRIVEN
Reactiveな3つの処理モード
18Copyright©2017 NTT corp. All Rights Reserved.
FULL / CHUNKED に共通の課題
Model Mono
Flux
19Copyright©2017 NTT corp. All Rights Reserved.
FULL / CHUNKED に共通の課題
Context
Engine
Model Mono
Flux
ArrayList
Mono Mono
AbstractView#resolveAsyncAttributes
CollectList
20Copyright©2017 NTT corp. All Rights Reserved.
DATA-DRIVENモード
Context
Engine
Model
ReactiveDataDriverContextVariable
wrapすることでresolutionを回避
… … …
ThymeleafがProcessorのように振る舞う
21Copyright©2017 NTT corp. All Rights Reserved.
DATA-DRIVEN & SSE
DATA-DRIVENモードの場合はデータ1件ごとに
部分的なHTMLをSSEで送信可能
<table>
<tr data-th-each=“name : ${names}”>
<td>[[${name}]]</td>
</tr>
</table>
+
Alice Bob Carol
event: head
id: 0
data: <table>
event: body
id: 1
data: <tr>
data: <td>Alice</td>
data: <tr>
event: tail
id: 4
data: </table>
・・・
22Copyright©2017 NTT corp. All Rights Reserved.
デモアプリ紹介
試合状況
コメント
23Copyright©2017 NTT corp. All Rights Reserved.
初期画⾯表⽰
Agent Controller
ReavtiveMongoTemplate
ReactiveMongoRepository
match/{matchId}
初期画⾯
リクエスト以前のコメント
対戦チーム情報など
24Copyright©2017 NTT corp. All Rights Reserved.
初期画⾯表⽰の実装 - MatchController
コメントのFluxを取得
コメントのFluxをReactiveDataDriverContextVariableで
warpしてModelに追加 → DATA-DRIVENモード
25Copyright©2017 NTT corp. All Rights Reserved.
デモアプリ紹介
動的に更新
26Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画
Agent Controller
ReavtiveMongoTemplate
ReactiveMongoRepository
match/{matchId}/statusStream
画⾯の⼀部
(SSEで送信)
試合状況
javascriptで画⾯に反映
27Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画
Agent Controller
ReavtiveMongoTemplate
ReactiveMongoRepository
画⾯の⼀部を⽣成
(SSEで送信)
新しい試合状況を取得
javascriptで画⾯に反映
得点や警告などの
イベントをランダム⽣成
新しいイベントを挿⼊
28Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画の実装 -
MatchEventInfoRepository
MongoDBのTailable Cursorを使⽤して
新しくinsertされたデータを取得し続ける
29Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画の実装 - MatchController
SSEで送信
Thymeleafで画⾯の⼀部を⽣成
DATA-DRIVEN モード
30Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画の実装 – match.html (js)
SSEで送信されてきた画⾯の⼀部を使って
画⾯を部分的に書き換える
部分⽣成対象
31Copyright©2017 NTT corp. All Rights Reserved.
デモアプリ紹介
動的に追加
32Copyright©2017 NTT corp. All Rights Reserved.
コメント描画
Agent Controller
ReavtiveMongoTemplate
ReactiveMongoRepository
match/{matchId}/commentStream?
timestamp=xxxxxxxx(初期リクエスト時刻)
json
(SSEで送信)
指定timestampより
後のコメント
javascriptで画⾯に反映
33Copyright©2017 NTT corp. All Rights Reserved.
コメント描画
Agent Controller
ReavtiveMongoTemplate
ReactiveMongoRepository
json
(SSEで送信)
javascriptで画⾯に反映
コメントをランダム⽣成
新しいコメントを取得
新しいコメントを挿⼊
34Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画の実装 -
MatchCommentRepository
MongoDBのTailable Cursorを使⽤して
新しくinsertされたデータを取得し続ける
35Copyright©2017 NTT corp. All Rights Reserved.
コメント描画の実装 - MatchController
jsonをSSEで送信
36Copyright©2017 NTT corp. All Rights Reserved.
試合状況描画の実装 – match.html (js)
SSEで送信されてきたjsonデータを使って
画⾯を部分的に書き換える
37Copyright©2017 NTT corp. All Rights Reserved.
• Thymeleaf 3 × WebFluxでReactiveなView出⼒
• 3つの処理モード
• FULL
• CHUNKED
• DATA-DRIVEN
• ⾒所満載のデモ
まとめ
是⾮⼀次資料(スライド / ソースコード)に
アクセスしてみて下さい!

Spring I/O 2017 報告 ThymeleafのWebFlux対応

  • 1.
    Copyright©2017 NTT corp.All Rights Reserved. Spring I/O 2017 報告会 ThymeleafのWebFlux対応 2017年6⽉29⽇ NTT ソフトウェアイノベーションセンタ 岩塚 卓弥
  • 2.
    2Copyright©2017 NTT corp.All Rights Reserved. • 名前:岩塚 卓弥 • 所属:NTT ソフトウェアイノベーションセンタ • NTTの研究所のうちソフトウェアを専⾨に扱う • ⾃部署ではソフトウェア⼯学を研究 • Springベースのグループ共通フレームワークの整備を担当 • Spring I/Oには2015年から3年連続参加 ⾃⼰紹介
  • 3.
    3Copyright©2017 NTT corp.All Rights Reserved. • Getting Thymeleaf Ready for Spring 5 and Reactive • Daniel Fernández – Thymeleaf lead • スライド • https://speakerdeck.com/dfernandez/o-2017-getting- thymeleaf-ready-for-spring-5-and-reactive • デモ • https://github.com/danielfernandez/reactive-matchday 今⽇の元ネタ(⼀次資料)
  • 4.
    4Copyright©2017 NTT corp.All Rights Reserved. • Thymeleaf 3を使⽤している • Thymeleaf 2を使⽤している • JSPを使⽤している • その他のテンプレートエンジンを使っている 会場アンケート:Thymeleaf 使ってますか
  • 5.
    5Copyright©2017 NTT corp.All Rights Reserved. 世界での利⽤状況 Spring Initializrで選択される テンプレートエンジンのうち 75%程度がThymeleaf Thymeleaf Freemarker Mustache Groovy Templates Velocity ⽉間DL数は22万以上 ⼀年で7万5千以上の伸び Spring I/O 2017 Keynoteより
  • 6.
    6Copyright©2017 NTT corp.All Rights Reserved. Spring MVC × Thymeleaf 3 の基本形 greeting.html 実装 出⼒
  • 7.
    7Copyright©2017 NTT corp.All Rights Reserved. Spring MVC × Thymeleaf 3 処理概略 TemplateName Context Engine Model Template +α HTML Controllerで設定したModel (Map<String, Object>)
  • 8.
    8Copyright©2017 NTT corp.All Rights Reserved. Spring MVC × Thymeleaf 3 処理概略 TemplateName Context Engine Model Template +α HTML Controllerから渡された View名を解決したもの ServletContextや パス変数等を追加
  • 9.
    9Copyright©2017 NTT corp.All Rights Reserved. Spring MVC × Thymeleaf 3 処理概略 TemplateName Context Engine Model Template +α HTMLTemplateを取得 TemplateとContextから HTMLを⽣成
  • 10.
    10Copyright©2017 NTT corp.All Rights Reserved. Spring MVC × Thymeleaf 3 処理概略 TemplateName Context Engine Model Template +α HTML HttpServletResponseに 書き込み
  • 11.
    11Copyright©2017 NTT corp.All Rights Reserved. Reactive化? TemplateName Context Engine Model Template +α HTML Blocking! Blocking!
  • 12.
    12Copyright©2017 NTT corp.All Rights Reserved. Reactive化? TemplateName Context Engine Model Template +α HTML Blocking! Reactive! 出⼒をPublisherに
  • 13.
    13Copyright©2017 NTT corp.All Rights Reserved. • FULL • CHUNKED • DATA-DRIVEN Reactiveな3つの処理モード
  • 14.
    14Copyright©2017 NTT corp.All Rights Reserved. FULLモード HTML Mono<DataBuffer>Engine ServerHttpResponseに書き込み HTMLを⼀括⽣成して⼀括出⼒ → 最もシンプルだがメモリ消費は⼤
  • 15.
    15Copyright©2017 NTT corp.All Rights Reserved. • FULL • CHUNKED • DATA-DRIVEN Reactiveな3つの処理モード
  • 16.
    16Copyright©2017 NTT corp.All Rights Reserved. CHUNKEDモード <!DOCTYPE html> … Flux<DataBuffer>Engine ServerHttpResponseに書き込み ・・・ … </html> HTMLを⼀定のバイト数ごとに区切って⽣成 → backpressureによって速度調整可能に
  • 17.
    17Copyright©2017 NTT corp.All Rights Reserved. • FULL • CHUNKED • DATA-DRIVEN Reactiveな3つの処理モード
  • 18.
    18Copyright©2017 NTT corp.All Rights Reserved. FULL / CHUNKED に共通の課題 Model Mono Flux
  • 19.
    19Copyright©2017 NTT corp.All Rights Reserved. FULL / CHUNKED に共通の課題 Context Engine Model Mono Flux ArrayList Mono Mono AbstractView#resolveAsyncAttributes CollectList
  • 20.
    20Copyright©2017 NTT corp.All Rights Reserved. DATA-DRIVENモード Context Engine Model ReactiveDataDriverContextVariable wrapすることでresolutionを回避 … … … ThymeleafがProcessorのように振る舞う
  • 21.
    21Copyright©2017 NTT corp.All Rights Reserved. DATA-DRIVEN & SSE DATA-DRIVENモードの場合はデータ1件ごとに 部分的なHTMLをSSEで送信可能 <table> <tr data-th-each=“name : ${names}”> <td>[[${name}]]</td> </tr> </table> + Alice Bob Carol event: head id: 0 data: <table> event: body id: 1 data: <tr> data: <td>Alice</td> data: <tr> event: tail id: 4 data: </table> ・・・
  • 22.
    22Copyright©2017 NTT corp.All Rights Reserved. デモアプリ紹介 試合状況 コメント
  • 23.
    23Copyright©2017 NTT corp.All Rights Reserved. 初期画⾯表⽰ Agent Controller ReavtiveMongoTemplate ReactiveMongoRepository match/{matchId} 初期画⾯ リクエスト以前のコメント 対戦チーム情報など
  • 24.
    24Copyright©2017 NTT corp.All Rights Reserved. 初期画⾯表⽰の実装 - MatchController コメントのFluxを取得 コメントのFluxをReactiveDataDriverContextVariableで warpしてModelに追加 → DATA-DRIVENモード
  • 25.
    25Copyright©2017 NTT corp.All Rights Reserved. デモアプリ紹介 動的に更新
  • 26.
    26Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画 Agent Controller ReavtiveMongoTemplate ReactiveMongoRepository match/{matchId}/statusStream 画⾯の⼀部 (SSEで送信) 試合状況 javascriptで画⾯に反映
  • 27.
    27Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画 Agent Controller ReavtiveMongoTemplate ReactiveMongoRepository 画⾯の⼀部を⽣成 (SSEで送信) 新しい試合状況を取得 javascriptで画⾯に反映 得点や警告などの イベントをランダム⽣成 新しいイベントを挿⼊
  • 28.
    28Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画の実装 - MatchEventInfoRepository MongoDBのTailable Cursorを使⽤して 新しくinsertされたデータを取得し続ける
  • 29.
    29Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画の実装 - MatchController SSEで送信 Thymeleafで画⾯の⼀部を⽣成 DATA-DRIVEN モード
  • 30.
    30Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画の実装 – match.html (js) SSEで送信されてきた画⾯の⼀部を使って 画⾯を部分的に書き換える 部分⽣成対象
  • 31.
    31Copyright©2017 NTT corp.All Rights Reserved. デモアプリ紹介 動的に追加
  • 32.
    32Copyright©2017 NTT corp.All Rights Reserved. コメント描画 Agent Controller ReavtiveMongoTemplate ReactiveMongoRepository match/{matchId}/commentStream? timestamp=xxxxxxxx(初期リクエスト時刻) json (SSEで送信) 指定timestampより 後のコメント javascriptで画⾯に反映
  • 33.
    33Copyright©2017 NTT corp.All Rights Reserved. コメント描画 Agent Controller ReavtiveMongoTemplate ReactiveMongoRepository json (SSEで送信) javascriptで画⾯に反映 コメントをランダム⽣成 新しいコメントを取得 新しいコメントを挿⼊
  • 34.
    34Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画の実装 - MatchCommentRepository MongoDBのTailable Cursorを使⽤して 新しくinsertされたデータを取得し続ける
  • 35.
    35Copyright©2017 NTT corp.All Rights Reserved. コメント描画の実装 - MatchController jsonをSSEで送信
  • 36.
    36Copyright©2017 NTT corp.All Rights Reserved. 試合状況描画の実装 – match.html (js) SSEで送信されてきたjsonデータを使って 画⾯を部分的に書き換える
  • 37.
    37Copyright©2017 NTT corp.All Rights Reserved. • Thymeleaf 3 × WebFluxでReactiveなView出⼒ • 3つの処理モード • FULL • CHUNKED • DATA-DRIVEN • ⾒所満載のデモ まとめ 是⾮⼀次資料(スライド / ソースコード)に アクセスしてみて下さい!