SlideShare a Scribd company logo
Submit Search
Upload
Spring Bootをはじめる時にやるべき10のこと
Report
Share
心 谷本
アクロクエストテクノロジー株式会社 - テクニカルコンサルタント at アクロクエストテクノロジー株式会社
Follow
•
97 likes
•
41,856 views
1
of
108
Spring Bootをはじめる時にやるべき10のこと
•
97 likes
•
41,856 views
Report
Share
Download Now
Download to read offline
Technology
Spring in Summer発表資料 (2015年8月28日)
Read more
心 谷本
アクロクエストテクノロジー株式会社 - テクニカルコンサルタント at アクロクエストテクノロジー株式会社
Follow
Recommended
怖くないSpring Bootのオートコンフィグレーション by
怖くないSpring Bootのオートコンフィグレーション
土岐 孝平
2.9K views
•
39 slides
これからSpringを使う開発者が知っておくべきこと by
これからSpringを使う開発者が知っておくべきこと
土岐 孝平
21.4K views
•
32 slides
入社1年目のプログラミング初心者がSpringを学ぶための手引き by
入社1年目のプログラミング初心者がSpringを学ぶための手引き
土岐 孝平
24.7K views
•
60 slides
Java ORマッパー選定のポイント #jsug by
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
90.1K views
•
66 slides
さくっと理解するSpring bootの仕組み by
さくっと理解するSpring bootの仕組み
Takeshi Ogawa
65.2K views
•
38 slides
今こそ知りたいSpring Batch(Spring Fest 2020講演資料) by
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
8.4K views
•
53 slides
More Related Content
What's hot
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー by
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
Masatoshi Tada
29.8K views
•
63 slides
Spring Boot × Vue.jsでSPAを作る by
Spring Boot × Vue.jsでSPAを作る
Go Miyasaka
14.9K views
•
31 slides
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc by
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Masatoshi Tada
6.8K views
•
68 slides
Form認証で学ぶSpring Security入門 by
Form認証で学ぶSpring Security入門
Ryosuke Uchitate
11.2K views
•
64 slides
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 - by
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
3.2K views
•
30 slides
Springを何となく使ってる人が抑えるべきポイント by
Springを何となく使ってる人が抑えるべきポイント
土岐 孝平
25K views
•
18 slides
What's hot
(20)
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー by Masatoshi Tada
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
Masatoshi Tada
•
29.8K views
Spring Boot × Vue.jsでSPAを作る by Go Miyasaka
Spring Boot × Vue.jsでSPAを作る
Go Miyasaka
•
14.9K views
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc by Masatoshi Tada
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Masatoshi Tada
•
6.8K views
Form認証で学ぶSpring Security入門 by Ryosuke Uchitate
Form認証で学ぶSpring Security入門
Ryosuke Uchitate
•
11.2K views
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 - by onozaty
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
•
3.2K views
Springを何となく使ってる人が抑えるべきポイント by 土岐 孝平
Springを何となく使ってる人が抑えるべきポイント
土岐 孝平
•
25K views
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup by Masatoshi Tada
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
Masatoshi Tada
•
14.5K views
SPAセキュリティ入門~PHP Conference Japan 2021 by Hiroshi Tokumaru
SPAセキュリティ入門~PHP Conference Japan 2021
Hiroshi Tokumaru
•
99.5K views
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説 by Masatoshi Tada
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
Masatoshi Tada
•
15.9K views
O/Rマッパーによるトラブルを未然に防ぐ by kwatch
O/Rマッパーによるトラブルを未然に防ぐ
kwatch
•
48.4K views
Javaのログ出力: 道具と考え方 by Taku Miyakawa
Javaのログ出力: 道具と考え方
Taku Miyakawa
•
74.3K views
Spring tools4 by Takuya Iwatsuka
Spring tools4
Takuya Iwatsuka
•
10.7K views
実運用して分かったRabbit MQの良いところ・気をつけること #jjug by Yahoo!デベロッパーネットワーク
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
Yahoo!デベロッパーネットワーク
•
24.3K views
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション by ssuser070fa9
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
ssuser070fa9
•
9.7K views
今さら聞けないDiとspring by 土岐 孝平
今さら聞けないDiとspring
土岐 孝平
•
24.8K views
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot by Toshiaki Maki
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
Toshiaki Maki
•
37.3K views
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話 by JustSystems Corporation
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
JustSystems Corporation
•
16.5K views
これから始めるSpringのwebアプリケーション by 土岐 孝平
これから始めるSpringのwebアプリケーション
土岐 孝平
•
19.2K views
FlutterでGraphQLを扱う by IgaHironobu
FlutterでGraphQLを扱う
IgaHironobu
•
2.9K views
Junitを使ったjavaのテスト入門 by Satoshi Kubo
Junitを使ったjavaのテスト入門
Satoshi Kubo
•
37.6K views
Viewers also liked
イマドキの現場で使えるJavaライブラリ事情 by
イマドキの現場で使えるJavaライブラリ事情
takezoe
24.8K views
•
38 slides
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View! by
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View!
心 谷本
1.7K views
•
59 slides
JJUG CCC 2015 Fall keynote by
JJUG CCC 2015 Fall keynote
心 谷本
5.1K views
•
98 slides
Spring Boot + Netflix Eureka by
Spring Boot + Netflix Eureka
心 谷本
41.2K views
•
83 slides
サバフェス 2016 Yahoo! ID連携のご紹介 〜OpenID Connect入門〜 by
サバフェス 2016 Yahoo! ID連携のご紹介 〜OpenID Connect入門〜
Masaru Kurahayashi
4.9K views
•
65 slides
Microserviceなんて最初からやるもんじゃ無かった by
Microserviceなんて最初からやるもんじゃ無かった
Akira Miki
70.5K views
•
31 slides
Viewers also liked
(20)
イマドキの現場で使えるJavaライブラリ事情 by takezoe
イマドキの現場で使えるJavaライブラリ事情
takezoe
•
24.8K views
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View! by 心 谷本
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View!
心 谷本
•
1.7K views
JJUG CCC 2015 Fall keynote by 心 谷本
JJUG CCC 2015 Fall keynote
心 谷本
•
5.1K views
Spring Boot + Netflix Eureka by 心 谷本
Spring Boot + Netflix Eureka
心 谷本
•
41.2K views
サバフェス 2016 Yahoo! ID連携のご紹介 〜OpenID Connect入門〜 by Masaru Kurahayashi
サバフェス 2016 Yahoo! ID連携のご紹介 〜OpenID Connect入門〜
Masaru Kurahayashi
•
4.9K views
Microserviceなんて最初からやるもんじゃ無かった by Akira Miki
Microserviceなんて最初からやるもんじゃ無かった
Akira Miki
•
70.5K views
Beginning Java EE 6 勉強会(6) #bje_study by Masato Kawamura
Beginning Java EE 6 勉強会(6) #bje_study
Masato Kawamura
•
3.2K views
OAuth / OpenID Connectを中心とするAPIセキュリティについて #yuzawaws by Tatsuo Kudo
OAuth / OpenID Connectを中心とするAPIセキュリティについて #yuzawaws
Tatsuo Kudo
•
13.4K views
WebAPIのこれまでとこれから by Yohei Yamamoto
WebAPIのこれまでとこれから
Yohei Yamamoto
•
29.6K views
OpenID Connect のビジネスチャンス by OpenID Foundation Japan
OpenID Connect のビジネスチャンス
OpenID Foundation Japan
•
6.5K views
Java でつくる低レイテンシ実装の技巧 by Ryosuke Yamazaki
Java でつくる低レイテンシ実装の技巧
Ryosuke Yamazaki
•
10.8K views
REST 入門 by Yohei Yamamoto
REST 入門
Yohei Yamamoto
•
6.2K views
金融 API 時代のセキュリティ: OpenID Financial API (FAPI) WG by Nat Sakimura
金融 API 時代のセキュリティ: OpenID Financial API (FAPI) WG
Nat Sakimura
•
13.2K views
今更聞けないOAuth2.0 by Takahiro Sato
今更聞けないOAuth2.0
Takahiro Sato
•
68.9K views
Office365のIdentity管理 by Naohiro Fujie
Office365のIdentity管理
Naohiro Fujie
•
36.4K views
なぜOpenID Connectが必要となったのか、その歴史的背景 by Tatsuo Kudo
なぜOpenID Connectが必要となったのか、その歴史的背景
Tatsuo Kudo
•
49.3K views
エンタープライズITでのOpenID Connect利用ガイドライン by Tatsuo Kudo
エンタープライズITでのOpenID Connect利用ガイドライン
Tatsuo Kudo
•
13.8K views
SAML / OpenID Connect / OAuth / SCIM 技術解説 - ID&IT 2014 #idit2014 by Nov Matake
SAML / OpenID Connect / OAuth / SCIM 技術解説 - ID&IT 2014 #idit2014
Nov Matake
•
98.8K views
Uberご紹介(髙橋正巳) by 一般社団法人シェアリングエコノミー協会
Uberご紹介(髙橋正巳)
一般社団法人シェアリングエコノミー協会
•
1.4K views
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜 by Masaru Kurahayashi
OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
Masaru Kurahayashi
•
146.9K views
Similar to Spring Bootをはじめる時にやるべき10のこと
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記 by
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
心 谷本
6K views
•
92 slides
QAエンジニアを通じて弊社の開発環境がより良くなる日 〜 OpenSTF 編 〜 by
QAエンジニアを通じて弊社の開発環境がより良くなる日 〜 OpenSTF 編 〜
gree_tech
7.5K views
•
92 slides
ドリコムを支える課金ライブラリを支えるJenkins by
ドリコムを支える課金ライブラリを支えるJenkins
Go Sueyoshi (a.k.a sue445)
5.1K views
•
59 slides
2015年5月期 AITCオープンラボ 「第二回 デジタルガジェット祭り!」 by
2015年5月期 AITCオープンラボ 「第二回 デジタルガジェット祭り!」
aitc_jp
1K views
•
54 slides
RPAって何、どんなことできるの by
RPAって何、どんなことできるの
株式会社オプト 仙台ラボラトリ
3K views
•
59 slides
[Agile Japan 2019]DXを実現するためにユーザ企業とSI企業が 今すぐとるべき3つのステップ by
[Agile Japan 2019]DXを実現するためにユーザ企業とSI企業が 今すぐとるべき3つのステップ
Shigeki Morizane
1.5K views
•
80 slides
Similar to Spring Bootをはじめる時にやるべき10のこと
(20)
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記 by 心 谷本
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
心 谷本
•
6K views
QAエンジニアを通じて弊社の開発環境がより良くなる日 〜 OpenSTF 編 〜 by gree_tech
QAエンジニアを通じて弊社の開発環境がより良くなる日 〜 OpenSTF 編 〜
gree_tech
•
7.5K views
ドリコムを支える課金ライブラリを支えるJenkins by Go Sueyoshi (a.k.a sue445)
ドリコムを支える課金ライブラリを支えるJenkins
Go Sueyoshi (a.k.a sue445)
•
5.1K views
2015年5月期 AITCオープンラボ 「第二回 デジタルガジェット祭り!」 by aitc_jp
2015年5月期 AITCオープンラボ 「第二回 デジタルガジェット祭り!」
aitc_jp
•
1K views
RPAって何、どんなことできるの by 株式会社オプト 仙台ラボラトリ
RPAって何、どんなことできるの
株式会社オプト 仙台ラボラトリ
•
3K views
[Agile Japan 2019]DXを実現するためにユーザ企業とSI企業が 今すぐとるべき3つのステップ by Shigeki Morizane
[Agile Japan 2019]DXを実現するためにユーザ企業とSI企業が 今すぐとるべき3つのステップ
Shigeki Morizane
•
1.5K views
iPhoneアプリ開発を楽に楽しくするサイトまとめ by Hiramatsu Ryosuke
iPhoneアプリ開発を楽に楽しくするサイトまとめ
Hiramatsu Ryosuke
•
4.6K views
どうする!?これからのCto c(仮) by Junya Tanaka
どうする!?これからのCto c(仮)
Junya Tanaka
•
732 views
スタートアップ向け!1人日でできるサービスの高速化方法と成果 by Koichiro Sumi
スタートアップ向け!1人日でできるサービスの高速化方法と成果
Koichiro Sumi
•
6.5K views
おすすめインフラ! for スタートアップ by Koichiro Sumi
おすすめインフラ! for スタートアップ
Koichiro Sumi
•
1.6K views
Soracom ug#10:SORACOM Techonology Camp夜の部!東京支部活動報告 by Haruka Yamashita
Soracom ug#10:SORACOM Techonology Camp夜の部!東京支部活動報告
Haruka Yamashita
•
277 views
Google apps scriptを使って業務改善 by dcubeio
Google apps scriptを使って業務改善
dcubeio
•
5.6K views
SoftLayerのAPIを活用した ポータルサービス「SETTA」 by softlayerjp
SoftLayerのAPIを活用した ポータルサービス「SETTA」
softlayerjp
•
1.2K views
Whomor spine勉強会 遠藤加筆_150114 by 幹也 芝辻
Whomor spine勉強会 遠藤加筆_150114
幹也 芝辻
•
3.5K views
IETF90 IoT関連WG報告 #isocjp by Kaoru Maeda
IETF90 IoT関連WG報告 #isocjp
Kaoru Maeda
•
3.1K views
技術選択とアーキテクトの役割 (要約版) by Toru Yamaguchi
技術選択とアーキテクトの役割 (要約版)
Toru Yamaguchi
•
5K views
Ladder of cqrs+es by Masaki Toyoshima
Ladder of cqrs+es
Masaki Toyoshima
•
6.9K views
ああ、素晴らしきTDD ~アプリとエンジニアの心に安寧を~ by Saiki Iijima
ああ、素晴らしきTDD ~アプリとエンジニアの心に安寧を~
Saiki Iijima
•
8.2K views
Coldfusionを活かすシステム企画をリーンスタートアップに学ぶ by masashi takehara
Coldfusionを活かすシステム企画をリーンスタートアップに学ぶ
masashi takehara
•
1.8K views
Instok[file makerを用いた弊社の取組について」 by 基演 伊藤
Instok[file makerを用いた弊社の取組について」
基演 伊藤
•
460 views
More from 心 谷本
プレゼンの技術 2 実践編 by
プレゼンの技術 2 実践編
心 谷本
72.9K views
•
90 slides
プレゼンの技術 1 考え方 by
プレゼンの技術 1 考え方
心 谷本
11.2K views
•
106 slides
プレゼンの技術 by
プレゼンの技術
心 谷本
134.2K views
•
112 slides
from old java to java8 - KanJava Edition by
from old java to java8 - KanJava Edition
心 谷本
2.9K views
•
91 slides
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡 by
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡
心 谷本
24.7K views
•
76 slides
from old Java to modern Java by
from old Java to modern Java
心 谷本
35.4K views
•
102 slides
More from 心 谷本
(10)
プレゼンの技術 2 実践編 by 心 谷本
プレゼンの技術 2 実践編
心 谷本
•
72.9K views
プレゼンの技術 1 考え方 by 心 谷本
プレゼンの技術 1 考え方
心 谷本
•
11.2K views
プレゼンの技術 by 心 谷本
プレゼンの技術
心 谷本
•
134.2K views
from old java to java8 - KanJava Edition by 心 谷本
from old java to java8 - KanJava Edition
心 谷本
•
2.9K views
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡 by 心 谷本
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡
心 谷本
•
24.7K views
from old Java to modern Java by 心 谷本
from old Java to modern Java
心 谷本
•
35.4K views
日本一細かいJavaOne2011報告 by 心 谷本
日本一細かいJavaOne2011報告
心 谷本
•
1.2K views
勝敗は常に見積もりで決まる〜Redmineを使った時間記録の話 by 心 谷本
勝敗は常に見積もりで決まる〜Redmineを使った時間記録の話
心 谷本
•
6.9K views
日本で二番目に「細かい」JavaOne2011報告 by 心 谷本
日本で二番目に「細かい」JavaOne2011報告
心 谷本
•
1K views
[関ジャバ]Java News 2011 Mar by 心 谷本
[関ジャバ]Java News 2011 Mar
心 谷本
•
831 views
Recently uploaded
さくらのひやおろし2023 by
さくらのひやおろし2023
法林浩之
94 views
•
58 slides
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20... by
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
NTT DATA Technology & Innovation
101 views
•
42 slides
The Things Stack説明資料 by The Things Industries by
The Things Stack説明資料 by The Things Industries
CRI Japan, Inc.
50 views
•
29 slides
Web3 Career_クレデン資料 .pdf by
Web3 Career_クレデン資料 .pdf
nanamatsuo
14 views
•
9 slides
01Booster Studio ご紹介資料 by
01Booster Studio ご紹介資料
ssusere7a2172
345 views
•
19 slides
「概念モデリング自動化に向けた第一歩」 ~ ChatGPT・Open AI 活用による開発対象のモデル化 by
「概念モデリング自動化に向けた第一歩」 ~ ChatGPT・Open AI 活用による開発対象のモデル化
Knowledge & Experience
12 views
•
34 slides
Recently uploaded
(11)
さくらのひやおろし2023 by 法林浩之
さくらのひやおろし2023
法林浩之
•
94 views
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20... by NTT DATA Technology & Innovation
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
NTT DATA Technology & Innovation
•
101 views
The Things Stack説明資料 by The Things Industries by CRI Japan, Inc.
The Things Stack説明資料 by The Things Industries
CRI Japan, Inc.
•
50 views
Web3 Career_クレデン資料 .pdf by nanamatsuo
Web3 Career_クレデン資料 .pdf
nanamatsuo
•
14 views
01Booster Studio ご紹介資料 by ssusere7a2172
01Booster Studio ご紹介資料
ssusere7a2172
•
345 views
「概念モデリング自動化に向けた第一歩」 ~ ChatGPT・Open AI 活用による開発対象のモデル化 by Knowledge & Experience
「概念モデリング自動化に向けた第一歩」 ~ ChatGPT・Open AI 活用による開発対象のモデル化
Knowledge & Experience
•
12 views
JJUG CCC.pptx by Kanta Sasaki
JJUG CCC.pptx
Kanta Sasaki
•
6 views
SSH応用編_20231129.pdf by icebreaker4
SSH応用編_20231129.pdf
icebreaker4
•
184 views
Windows 11 information that can be used at the development site by Atomu Hidaka
Windows 11 information that can be used at the development site
Atomu Hidaka
•
76 views
SNMPセキュリティ超入門 by mkoda
SNMPセキュリティ超入門
mkoda
•
188 views
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料) by NTT DATA Technology & Innovation
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
•
17 views
Spring Bootをはじめる時にやるべき10のこと
1.
Spring Bootをはじめる時に やるべき10のこと #bootきのこ Shin Tanimoto Acroquest
Technology Co., LTD
2.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 皆さん 用意はいいですか? 2
3.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 鈴木会長は こっちじゃないぞ? 3
4.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. では、始めましょう! 4
5.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved. 自己紹介 5 • 谷本 心 (Shin Tanimoto) - Acroquest Technology株式会社 - 開発&トラブルシュート教育 - JavaOneスピーカー - JJUG / 関ジャバ / S2JSFコミッタ - Twitter : @cero_t (日本語) - Facebook : shin.tanimoto (英語)
6.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6 Struts + Hibernate Seasar2 + S2JSF + S2Dao Click + Guice + Mirage Spring MVC + Hibernate
7.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. フレームワークに 求めていること 7
8.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 開発効率 生産性 8
9.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. ではなくて 9
10.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. ハマらない ミスしない ミスをリカバリできる 10
11.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. ひとつハマれば 3人日が奪われ 11
12.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. ひとつミスしていれば 商用障害が起き 12
13.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. リカバリできずに 今日も徹夜 13
14.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. ハマらない ミスしない ミスをリカバリできる 14
15.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. そのための Spring Boot 15
16.
Spring Bootをはじめる時に やるべき10のこと #bootきのこ Shin Tanimoto Acroquest
Technology Co., LTD
17.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 17 #1 SpringBootを知る
18.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 1. Spring Bootを知る Spring Bootとは 複雑化したSpringプロジェクト群を使った開発を シンプルに開始できる仕組み 18
19.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 19 Springベースの フルスタック プラットフォーム
20.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 1. Spring Bootを知る フルスタックプラットフォーム View層、コンテナ層、データアクセス層 監視、非同期メッセージング、クラウド対応など 様々な機能を「Spring Boot」という共通の プラットフォーム上で利用できる。 20
21.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 1. Spring Bootを知る フルスタックプラットフォームでないと 自分で様々なフレームワークを組み合わせると もちろん自由に選べる反面、 設定の記述や、動作検証などが必要になる。 ここに「ハマり」要因がある。 21
22.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 1. Spring Bootを知る あまり強調しない方が良いこと Microservices向けフレームワーク 別にそれが目的ではない Executable JAR ≠ Microservices XMLを書かない ymlや設定クラスを少し作る 22
23.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 23 #1 Spring Bootなら 組み合わせでハマらない!
24.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 24 #2 はじめての Spring Boot
25.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 2. はじめてのSpring Boot 新しいプロダクトの利用時あるある ドキュメントがない。 ドキュメントが英語しかない。 ブログがない。ノウハウがない。 とりあえず少しずつググりながら 場当たり対応で何とか凌ぐ。 そんなことをしているから「設計ミス」をする。 25
26.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 2. はじめてのSpring Boot はじめてのSpring Boot 26 @makingの力作 Spring Bootを用いた 開発、試験、デプロイなどを まるっと習得できる こっちの入門スライドもオススメ http://www.slideshare.net/ makingx/grails-30-spring-boot
27.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 27 #2 はじめてのSpring Bootで 初期学習を効率化!
28.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 28 #3 Spring Initializr
29.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 3. Spring Initializr プロジェクト立ち上げ時あるある pom.xmlを書いて、必要な依存ライブラリを列挙する。 ・・・のは面倒だから、exampleプロジェクトを探して 不要なソースコードを削除する。 なんか不要なJARが混入している なぜかバージョン違いのJARが混入する 頑張ってビルドファイルを書いたけど、なぜか動かない。 ここに「ミス」と「ハマり」要因がある。 29
30.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 3. Spring Initializr Spring Initializrとは https://start.spring.io/ Spring Bootプロジェクトの雛形を作る Maven or Gradleのプロジェクト作成 利用するプロジェクトやライブラリを選択できる Web、JDBC、Security、AOP、 JPA、Thymeleafなど つまずかずにスタートできる! 30
31.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 3. Spring Initializr 使い方 https://start.spring.io/ に行く。 必要な情報と、利用するモジュールを選ぶ。 Actuatorおすすめ Generate Projectをクリック。 ダウンロードしたzipを解凍する。 IDEにインポートする。 以下のいずれかで実行する。 mainメソッドを実行する mvn spring-boot:run 31
32.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 32 #3 Spring Initializrなら 初期構築でミスしない!
33.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 33 #4 pom.xmlの設計
34.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 4. pom.xmlの設計 pom.xmlあるある 複数モジュールを作る時、依存JARのバージョンを 複数のpom.xmlに重複して書いている。 そしてJARのバージョン違いが発生する 親子モジュールとか難しいから、 単一モジュールで行くぜー! WebAPIとバッチがなぜか同じJARに入ってる 34
35.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 4. pom.xmlの設計 pom.xmlのグッドプラクティス デプロイ単位、ライフサイクル単位で分割する 共通部分を切り出す フレームワーク部分 自動生成したエンティティ しかしそうすると、前述したJARの バージョン違い問題が起きる・・・? 35
36.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 4. pom.xmlの設計 pom.xmlのグッドプラクティス 依存JARのバージョンは、親のpom.xmlに書く <dependencyManagement> を使ってバージョンを定義する Spring IO platformを使う http://platform.spring.io/platform/ 大げさな名前だが、ただのpom.xml Spring関連モジュールだけでなく、 著名なプロダクトも含むバージョンを規定したpom.xml commons-lang、guice、joda-time、jruby、、、 Version1.1.4では552個のモジュールのバージョンが規定されている 36
37.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 37 #4 Spring IO platformで pom.xmlをシンプルに!
38.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 38 #5 Controllerの共通設定
39.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 突然ですが、 JSR 310 Date and Time APIの LocalDateクラスってご存じですか? LocalDate : 日付のみ。時間なし。 LocalTime : 時間のみ。日付なし。 LocalDateTime : 日付も時間もあり。 39
40.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 java.util.DateやCalendarはハマりやすい Dateを使って比較する際、日付だけで良いのに 余計な時分秒が入っているせいで、判定を誤る。 Calendarで時分秒に0を指定したけど ミリ秒に余計な値が入っていて、判定を誤る。 SimpleDateFormatがスレッドセーフでないことを 知らずに、商用環境で問題が起きる。 40
41.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 JSR 310をSpring Bootでも使いたい できること yyyy-MM-dd形式の日付 JSONリクエスト → LocalDateフィールド できないこと yyyy/MM/dd形式の日付 LocalDateフィールド → JSONレスポンス 41
42.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 ControllerでLocalDateを使う Controllerで利用するJacksonをカスタマイズする Controllerの引数・戻り値のオブジェクトと JSONリクエスト・レスポンスは、 Jacksonでシリアライズ・デシリアライズされる。 Jackson2ObjectMapperBuilderを 戻すメソッドに@Beanをつけることで カスタマイズできる。 42
43.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 @Bean public Jackson2ObjectMapperBuilder jacksonBuilder() { return Jackson2ObjectMapperBuilder.json() .indentOutput(true) .serializerByType(LocalDate.class, new JsonSerializer<LocalDate>() { @Override public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(value.format(DATE_FORMATTER)); } }) .deserializerByType(LocalDate.class, new JsonDeserializer<LocalDate>() { @Override public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { return LocalDate.parse(jp.getValueAsString(), DATE_PARSER); } }) .modules(new JSR310Module()); } 43
44.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 @Bean public Jackson2ObjectMapperBuilder jacksonBuilder() { return Jackson2ObjectMapperBuilder.json() .indentOutput(true) .serializerByType(LocalDate.class, new JsonSerializer<LocalDate>() { @Override public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(value.format(DATE_FORMATTER)); } }) .deserializerByType(LocalDate.class, new JsonDeserializer<LocalDate>() { @Override public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { return LocalDate.parse(jp.getValueAsString(), DATE_PARSER); } }) .modules(new JSR310Module()); } 44 出力するJSONを 読みやすく LocalDateの シリアライズと デシリアライズ 他のJSR 310クラスも 使えるようにしておく
45.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 /** 日付フォーマット */ protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); /** 日付パースフォーマット */ protected static final DateTimeFormatter DATE_PARSER = DateTimeFormatter.ofPattern(“y[-][/]M[-][/]d"); 45
46.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5. Controllerの共通設定 /** 日付フォーマット */ protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); /** 日付パースフォーマット */ protected static final DateTimeFormatter DATE_PARSER = DateTimeFormatter.ofPattern(“y[-][/]M[-][/]d"); 入力は柔軟に、出力は厳格に。 46 フォーマット時は 0埋め、 ハイフン区切り パース時は 0埋め、区切りを 少し自由に
47.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 47 #5 ControllerでLocalDateを 使って日付判定ミスを防ぐ!
48.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 48 #6 トランザクション 境界の設定
49.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6. トランザクション境界の設定 トランザクションあるある Controllerをトランザクション境界にする 処理の途中で一度コミットしたいけどできない 非同期処理呼び出しの前にコミットとか 途中でコミットできるような仕組みを 無理に作ったら全体的な整合性が崩れた 性能改善のためのリードレプリカを作りたいが、 そもそもアクセスを振り分けられない 49
50.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6. トランザクション境界の設定 Service層をトランザクション境界にする Controllerの次の層をトランザクション境界にする 処理の単位が明確になる Service層からreturnすればコミット、 例外で戻ればロールバック。 Service層のクラスすべてに @Transactionalアノテーションをつける 50
51.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6. トランザクション境界の設定 原則、Read Onlyトランザクションを使う Service層のクラスすべてに @Transactional(readOnly = true) をつける Insert / Update / Deleteが発生する時だけ メソッドに @Transactional(readOnly = false) を つける ReadOnlyトランザクションだけを リードレプリカに振り分ける 51
52.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6. トランザクション境界の設定 @Service @Transactional(readOnly = true) public class EmployeeService { @Autowired protected EmployeeDao employeeDao; public Employee getEmployee(Integer id) { return employeeDao.selectById(id); } @Transactional(readOnly = false) public int createEmployee(Employee employee) { return employeeDao.insert(employee); } } 52
53.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6. トランザクション境界の設定 @Service @Transactional(readOnly = true) public class EmployeeService { @Autowired protected EmployeeDao employeeDao; public Employee getEmployee(Integer id) { return employeeDao.selectById(id); } @Transactional(readOnly = false) public int createEmployee(Employee employee) { return employeeDao.insert(employee); } } 53 クラスには readOnly = true 更新系メソッドに readOnly = false
54.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 54 #6 ServiceクラスにRead Onlyな トランザクションを設けて 将来に備える!
55.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 55 #7 O/Rマッパーの選択
56.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 O/Rマッパーあるある とりあえずHibernate 思ったのと違うSQLが発行された 1リクエストでSQLが1万回発行された selectしたタイミングで一意制約違反が出た キャッシュが想定外の動きをした。 要するにハマる 56
57.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 O/Rマッパーあるある じゃぁMyBatis Spring Bootで標準対応していない 1.3で標準対応されるかも https://github.com/spring-projects/spring-boot/pull/3692 SQLを書いたXMLをフォーマットしたら インデントが全部消えた > とか < のエスケープ 57
58.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 O/Rマッパーあるある じゃぁJdbcTemplate なんかAPIが古くさい(Spring 2.0時代のAPI) publicフィールドが使えない JSR 310に対応していない 58
59.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 59 そこで Bootiful SQL Template
60.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 Bootiful SQL Template JdbcTemplate / NamedParameterJdbcTemplateの 独自ラッパー SQLファイルを書ける(FreeMarker形式も可) モダンなAPI publicフィールドが使える JSR 310に対応(ZonedDateTimeにも) https://github.com/cero-t/sqltemplate 60
61.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 @Autowired protected SqlTemplate sqlTemplate; public List<Employee> selectByCondition(EmployeeCondition condition) { return sqlTemplate.forList("sql/EmployeeDao/selectByCondition.sql", Employee.class, condition); } 61
62.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 @Autowired protected SqlTemplate sqlTemplate; public List<Employee> selectByCondition(EmployeeCondition condition) { return sqlTemplate.forList("sql/EmployeeDao/selectByCondition.sql", Employee.class, condition); } 62 モダンでサクっと 使えるAPI IntelliJなら Command(Ctrl) + クリックで SQLファイルにジャンプ
63.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 SELECT * FROM emp WHERE 1 = 1 <#if name??> AND ename like '%' || :name || '%' </#if> <#if hiredateFrom??> AND :hiredateFrom < hiredate </#if> <#if hiredateTo??> AND hiredate < :hiredateTo </#if> <#if deptno??> AND deptno = :deptno </#if> 63
64.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7. O/Rマッパーの選択 SELECT * FROM emp WHERE 1 = 1 <#if name??> AND ename like '%' || :name || '%' </#if> <#if hiredateFrom??> AND :hiredateFrom < hiredate </#if> <#if hiredateTo??> AND hiredate < :hiredateTo </#if> <#if deptno??> AND deptno = :deptno </#if> 64 FreeMarker形式の テンプレートが利用可能 ANDを自動的に消す機能が なくてごめんな
65.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 65 #7 Bootiful SQL Templateで SQLを書いてハマり知らず
66.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 66 #8 例外処理の共通化
67.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 例外処理あるある 個別の開発者任せ もちろん死ぬ フレームワークが返す例外(バリデーションなど)と、 アプリケーションが返す例外でJSONの形式が違う クライアント側で判別に失敗して死ぬ 個別のエラーコードを定義しておいたので 全部ソースコード内に書く 守らない人がいて死ぬ 67
68.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 例外処理は共通化する ApplicationException extends RuntimeExceptionを 作って必ずこれを使う エラー種別をenumに定義しておき、 ApplicationExceptionのコンストラクタの 第一引数に必ず渡す エラー種別と、HTTPステータスやエラーコード、 エラーメッセージを紐付けて管理する 68
69.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 public class ApplicationException extends RuntimeException { Throwable cause; Object[] args; private HttpErrors error; public AppException(HttpErrors error, Throwable cause, String... args) { super(); this.error = error; this.args = args; this.cause = cause; } // その他のコンストラクタ、cause、args、errorのgetterは割愛 public String getMessage() { if (args != null) { return "[" + error.name() + "]" + MessageFormat.format(error.getMessage(), args); } return "[" + error.name() + "]" + error.getMessage(); } } 69
70.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 public class ApplicationException extends RuntimeException { Throwable cause; Object[] args; private HttpErrors error; public AppException(HttpErrors error, Throwable cause, String... args) { super(); this.error = error; this.args = args; this.cause = cause; } // その他のコンストラクタ、cause、args、errorのgetterは割愛 public String getMessage() { if (args != null) { return "[" + error.name() + "]" + MessageFormat.format(error.getMessage(), args); } return "[" + error.name() + "]" + error.getMessage(); } } 70 第一引数で エラー種別を受け取る
71.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 public interface HttpErrors { /** * HTTPステータスを取得します。 * @return HTTPステータス */ HttpStatus getStatus(); /** * メッセージを取得します。 * @return メッセージ */ String getMessage(); /** * エラー名を取得します。 * @return エラー名 */ String name(); } 71
72.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 public enum Errors implements HttpErrors { USER_NOT_FOUND(HttpStatus.NOT_FOUND, "入力したIDに対応するユーザーが存在しません。userId={0}"), UNEXPECTED(HttpStatus.INTERNAL_SERVER_ERROR, "想定外のエラーが発生しました。 : {0}"); protected HttpStatus status; protected String message; Errors(HttpStatus status, String message) { this.status = status; this.message = message; } @Override public HttpStatus getStatus() { return status; } @Override public String getMessage() { return message; } } 72
73.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 public enum Errors implements HttpErrors { USER_NOT_FOUND(HttpStatus.NOT_FOUND, "入力したIDに対応するユーザーが存在しません。userId={0}"), UNEXPECTED(HttpStatus.INTERNAL_SERVER_ERROR, "想定外のエラーが発生しました。 : {0}"); protected HttpStatus status; protected String message; Errors(HttpStatus status, String message) { this.status = status; this.message = message; } @Override public HttpStatus getStatus() { return status; } @Override public String getMessage() { return message; } } 73 エラーを列挙
74.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 例外処理ハンドリングも共通化する ApplicationExceptionと RuntimeExceptionと フレームワークが返す例外で すべて同じ例外ハンドリングをする 74
75.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 @ControllerAdvice public class ControllerExceptionHandler extends ResponseEntityExceptionHandler { /** ロガー */ protected final Log logger = LogFactory.getLog(getClass()); @ExceptionHandler(value = ApplicationException.class) @ResponseBody public ResponseEntity<RestError> handleAppException(HttpServletRequest request, ApplicationException ex) { return handleError(request, ex.getError(), ex, ex.getArgs()); } @ExceptionHandler(value = RuntimeException.class) @ResponseBody public ResponseEntity<RestError> handleException(HttpServletRequest request, RuntimeException ex) { return handleError(request, Errors.UNEXPECTED, ex, ex.toString()); } 75
76.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 @ControllerAdvice public class ControllerExceptionHandler extends ResponseEntityExceptionHandler { /** ロガー */ protected final Log logger = LogFactory.getLog(getClass()); @ExceptionHandler(value = ApplicationException.class) @ResponseBody public ResponseEntity<RestError> handleAppException(HttpServletRequest request, ApplicationException ex) { return handleError(request, ex.getError(), ex, ex.getArgs()); } @ExceptionHandler(value = RuntimeException.class) @ResponseBody public ResponseEntity<RestError> handleException(HttpServletRequest request, RuntimeException ex) { return handleError(request, Errors.UNEXPECTED, ex, ex.toString()); } 76 独自のApplicationExceptionと 想定しないRuntimeExceptionの両方を 同じ方式でハンドリング
77.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 protected ResponseEntity<RestError> handleError(HttpServletRequest request, HttpErrors error, Exception ex, Object... args) { String message = MessageFormat.format(error.getMessage(), args); if (error.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR) { logger.error(message, ex); } else { logger.debug(message, ex); } if (error.getStatus() == HttpStatus.UNAUTHORIZED) { return new ResponseEntity<>(error.getStatus()); } RestError restError = new RestError(); restError.path = request.getRequestURI(); restError.error = error.name(); restError.status = error.getStatus() .value(); restError.message = message; restError.exception = ex.getClass() .getName(); return new ResponseEntity<>(restError, error.getStatus()); } 77
78.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 protected ResponseEntity<RestError> handleError(HttpServletRequest request, HttpErrors error, Exception ex, Object... args) { String message = MessageFormat.format(error.getMessage(), args); if (error.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR) { logger.error(message, ex); } else { logger.debug(message, ex); } if (error.getStatus() == HttpStatus.UNAUTHORIZED) { return new ResponseEntity<>(error.getStatus()); } RestError restError = new RestError(); restError.path = request.getRequestURI(); restError.error = error.name(); restError.status = error.getStatus() .value(); restError.message = message; restError.exception = ex.getClass() .getName(); return new ResponseEntity<>(restError, error.getStatus()); } 78 例外オブジェクトへの変換
79.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 @Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { RestError restError = new RestError(); if (request instanceof ServletWebRequest) { restError.path = ((ServletWebRequest) request).getRequest() .getRequestURI(); } else { restError.path = request.getContextPath(); } restError.error = status.getReasonPhrase(); restError.status = status.value(); restError.message = ex.getMessage(); restError.exception = ex.getClass() .getName(); return new ResponseEntity<>(restError, status); } } 79
80.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8. 例外処理の共通化 @Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { RestError restError = new RestError(); if (request instanceof ServletWebRequest) { restError.path = ((ServletWebRequest) request).getRequest() .getRequestURI(); } else { restError.path = request.getContextPath(); } restError.error = status.getReasonPhrase(); restError.status = status.value(); restError.message = ex.getMessage(); restError.exception = ex.getClass() .getName(); return new ResponseEntity<>(restError, status); } } 80 このオーバーライドで Spring MVCが投げる例外を ハンドリングできる
81.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 81 #8 すべての例外を共通して ハンドリングせよ!
82.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 82 #9 AOPによるロギング
83.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 9. AOPによるロギング AOPとは アプリケーション横断的に行う処理 トランザクションのコミットやロールバックもAOPで実現されている オススメは、AOPによる自動ロギング Controller / Service / DaoのIn/Outでロギング デバッグ時に、アプリケーションの挙動がとてもよく分かる ログレベルに応じて引数、戻り値なども出す SpringではXMLやアノテーションでAOPの対象を記述することができる 正直、アノテーションの記述はイマイチ。分かりづらい。 記述性はGuice > Seasar > Spring。 83
84.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 9. AOPによるロギング @Aspect @Component public class DumpLogInterceptor { protected Logger logger = LoggerFactory.getLogger(getClass()); @Around("execution(* ninja.cero.springboot..*.*(..)) && (bean(*Controller) || bean(*Service) || bean(*Dao))") public Object dump(ProceedingJoinPoint joinPoint) throws Throwable { try { logger.debug("BEGIN - " + toCall(joinPoint)); logger.trace("with args - " + ToStringBuilder.reflectionToString(joinPoint.getArgs(), ToStringStyle.SHORT_PREFIX_STYLE)); Object retValue = joinPoint.proceed(joinPoint.getArgs()); logger.debug("END - " + toCall(joinPoint)); logger.trace( "with return - " + ToStringBuilder.reflectionToString(retValue, ToStringStyle.SHORT_PREFIX_STYLE)); return retValue; } catch (Throwable th) { logger.debug("END throw - " + toCall(joinPoint)); logger.debug("Exception: " + th); throw th; } } } 84
85.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 9. AOPによるロギング @Aspect @Component public class DumpLogInterceptor { protected Logger logger = LoggerFactory.getLogger(getClass()); @Around("execution(* ninja.cero.springboot..*.*(..)) && (bean(*Controller) || bean(*Service) || bean(*Dao))") public Object dump(ProceedingJoinPoint joinPoint) throws Throwable { try { logger.debug("BEGIN - " + toCall(joinPoint)); logger.trace("with args - " + ToStringBuilder.reflectionToString(joinPoint.getArgs(), ToStringStyle.SHORT_PREFIX_STYLE)); Object retValue = joinPoint.proceed(joinPoint.getArgs()); logger.debug("END - " + toCall(joinPoint)); logger.trace( "with return - " + ToStringBuilder.reflectionToString(retValue, ToStringStyle.SHORT_PREFIX_STYLE)); return retValue; } catch (Throwable th) { logger.debug("END throw - " + toCall(joinPoint)); logger.debug("Exception: " + th); throw th; } } } 85 この記述でController / Service Daoの実行前後に処理を差し込む
86.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 86 #9 AOPによるロギングで 問題発生時のリカバリを 高速化しよう
87.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 87 #10 テスト設計
88.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 テストあるある とりあえず、手動でテストしようぜ! → 回帰試験で死ぬ。 ロジックがあるControllerからテストすればOK! → バリデーションの設定ミスで死ぬ。 通常使うComponentとモックのComponentは @Profileで切り替えるのがSpring流! → 管理できなくなってきて死ぬ。 Spring Bootはend-to-endでテストしやすいから end-to-endのテストでカバレッジ80%を目指そう! → そして死ぬ。 88
89.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 テストのグッドプラクティス Controller以降をJUnitでテストする。 カバレッジは最低60%、できれば80%を目指す。 外部サービス呼び出し部分は、モック化する(後述) 例外を任意で発生させたい場合も、モック化すると良い。 無名クラスを活用したモックを作れるようになろう。 end-to-endのJUnitを書いて、 正常系1本とバリデーション部分をテストする。 JUnitのテストクラスに @IntegrationTest(“server.port=0”) をつけ、 RestTemplateを用いてテストする。 バリデーションの試験は、end-to-endでしかできない。 89
90.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @Transactional public class EmployeesControllerTest { @Autowired EmployeesController controller; @Test public void testGetAll() { List<EmployeesOut> employees = controller.getEmployees(); // TODO: assert } 90
91.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @Transactional public class EmployeesControllerTest { @Autowired EmployeesController controller; @Test public void testGetAll() { List<EmployeesOut> employees = controller.getEmployees(); // TODO: assert } 91 テストの時に必ずつけるアノテーション。 トランザクションを有効にして 試験が終わったら自動でロールバック。 TestContextConfigはあとで。
92.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @WebAppConfiguration @IntegrationTest("server.port=0") @Transactional public class EmployeesTest { @Value("http://localhost:${local.server.port}/employees") String baseUrl; @Autowired RestTemplate restTemplate; @Test public void testGetList() { ResponseEntity<List> out = restTemplate.getForEntity(baseUrl, List.class); // TODO: assert } 92
93.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @WebAppConfiguration @IntegrationTest("server.port=0") @Transactional public class EmployeesTest { @Value("http://localhost:${local.server.port}/employees") String baseUrl; @Autowired RestTemplate restTemplate; @Test public void testGetList() { ResponseEntity<List> out = restTemplate.getForEntity(baseUrl, List.class); // TODO: assert } 93 @WebAppConfigurationと @IntegrationTestをつけて Tomcatを起動 RestTemplateでアクセス URLを設定
94.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 テストのTips schema.sqlとdata.sqlでデータ投入する /src/test/resources にschema.sqlとdata.sqlを 置いておけば、JUnitの起動前にのみ実行される。 /src/main/resources に置いておけば 通常起動時に実行される(動作確認向け) 事故ってproduction環境で動かさないように! Controllerのテストと、end-to-endのテストは同じapplication.ymlでテストする end-to-endの試験も自動化するため。 end-to-endのテストは、ついつい範囲を広げたくなるが 自動化する試験と、そうでない試験は分けるべき。 94
95.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 テストのTips @Componentのモックは、 @Profileよりも@Primaryをつけた方が良い 外部サービスの呼び出しなどをモック化する場合、 モック化したい部分を @Autowired にしておく。 モッククラスを /src/test/java 以下で作成し、 @Component (@Bean) と@Primaryアノテーションを つければ、JUnit実行時のみ利用される。 95
96.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 public interface Context { /** * セッションIDを取得します。 * @return セッションID */ String getSessionId(); } 96 本体コード側にある インタフェース。
97.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 public class RequestContext implements Context { protected HttpServletRequest request; public RequestContext(HttpServletRequest request) { this.request = request; } @Override public String getSessionId() { return request.getSession().getId(); } } 97 本体コード側にある実装。 HttpServletRequestを使っているので JUnit時にはエラーが起きる
98.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @Configuration public class TestContextConfig { @Bean @Primary public Context context() { return new Context() { @Override public String getSessionId() { return "JUNIT"; } }; } } 98
99.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @Configuration public class TestContextConfig { @Bean @Primary public Context context() { return new Context() { @Override public String getSessionId() { return "JUNIT"; } }; } } 99 テスト側の設定クラス。 ここに@Primaryを書けば このコンポーネントが 優先して使われる。
100.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @Transactional public class EmployeesControllerTest { @Autowired EmployeesController controller; @Test public void testGetAll() { List<EmployeesOut> employees = controller.getEmployees(); // TODO: assert } 100
101.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {BlankWeb.class, TestContextConfig.class}) @Transactional public class EmployeesControllerTest { @Autowired EmployeesController controller; @Test public void testGetAll() { List<EmployeesOut> employees = controller.getEmployees(); // TODO: assert } 101 テスト側で、先ほど書いた Configurationを明示的に読み込む
102.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10. テスト設計 テストのTips /src/test/java 側に作ったテスト用の @Primary つき@Component (@Bean) は end-to-endのサーバ側にも適用されるので サーバ側でもモックを使いやすい たぶんこれ相当便利。 102
103.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 103 まとめ
104.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 104 スライド読み直せ!
105.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 105 One more thing…
106.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 106 今日紹介したソースは GitHubで公開中!
107.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved.Copyright © Acroquest Technology Co., Ltd. All rights reserved. 107 https://github.com/cero-t/ spring-boot-kinoko-2015
108.
Copyright © Acroquest
Technology Co., Ltd. All rights reserved. 108 Enjoy Spring Boot!