148
JSUG 2015 Spring in Summer ~ 夏なのにSpring 菊池 陽一

Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Embed Size (px)

Citation preview

Page 1: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

JSUG 2015 Spring in Summer ~ 夏なのにSpring 菊池 陽一

Page 2: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

菊池 陽一 Github: yo1000 hatena: Yoichi-KIKUCHI

Spring 歴: 5年 2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring 適用を模索

Page 3: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

みなさん

Page 4: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring どんなふうに 使っていますか?

Page 5: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 6: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 7: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 8: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 9: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 10: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

• 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト

Page 11: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

なんにでも 適用できますよね (とくにバックエンドシステムでは)

Page 12: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

非常に多機能かつ 柔軟に設計されている

Spring ならでは

Page 13: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Java をメインに システム構築して いるのであれば

Page 14: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を 選ばない手はない

Page 15: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

むしろ

Page 16: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring に非ずんば Java に非ず

Page 17: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

現在 それくらい 採用の広がっている 実感があります

Page 18: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

たとえば Atlassian

Confluence では ランタイムオブジェクトの管理に Spring を使用している

Page 19: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

たとえば JetBrains

TeamCity では 独自拡張した Spring コンテナを使用している

Page 20: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

たとえば JetBrains

サードパーティ製フルスタックフレームワークで IntelliJ のデフォルトサポートが あるのは Spring のみ!

Page 21: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

現在 国外のみならず 国内でも広く認知され 採用に至っている

Page 22: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

そんな Spring ですが 実際の業務適用に ついてはというと...

Page 23: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

いままさに仕掛中!とかこれからやりたい!とか

Page 24: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

そこで これまでの 5年すこしで感じた Spring についての あれこれをご紹介

Page 25: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

株式会社リクルートライフスタイル 菊池 陽一

Page 26: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

株式会社リクルートライフスタイル 菊池 陽一

Page 27: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索

2007.11Spring Framework 2.5

2009.12Spring Framework 3.0

2011.12Spring Framework 3.1

2013.12 Spring Framework 4.0

略歴

Page 28: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索

2007.11Spring Framework 2.5

2009.12Spring Framework 3.0

2011.12Spring Framework 3.1

2013.12 Spring Framework 4.0

略歴

バッドノウハウ収集期

Page 29: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索

2007.11Spring Framework 2.5

2009.12Spring Framework 3.0

2011.12Spring Framework 3.1

2013.12 Spring Framework 4.0

略歴

ベタープラクティス実践期

Page 30: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ収集期当時そんなつもりは全くありませんでしたが 振り返ってみるとバッドノウハウが多かった...

Page 31: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.0 GA ベース

● MVC フレームワークには Wicket を採用

● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターンにより実装

• bean 定義でサービス同士を相互に呼び出せるような仕組みを作りこんでいた

Page 32: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.0 GA ベース

● MVC フレームワークには Wicket を採用

● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターンにより実装

• bean 定義でサービス同士を相互に呼び出せるような仕組みを作りこんでいた

Good!

Page 33: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.0 GA ベース

● MVC フレームワークには Wicket を採用

● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターンにより実装

• bean 定義でサービス同士を相互に呼び出せるような仕組みを作りこんでいた

Good!

Bad!!

Page 34: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.0 GA ベース

● MVC フレームワークには Wicket を採用

● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターンにより実装

• bean 定義でサービス同士を相互に呼び出せるような仕組みを作りこんでいた

Good!

Bad!!

Bad!!

Page 35: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

何が良くなかったのか

Page 36: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

一般的な Spring Project

Page 37: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Page 38: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Page 39: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Request

Page 40: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Page 41: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Page 42: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

Request

Page 43: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準としていた フレームワーク

Page 44: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

Page 45: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

MVC フレームワークを Wicket に固定していた

Wicket

Controller

View

Page 46: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

MVC フレームワークを Wicket に固定していた

Wicket

Controller

View

Bad!!

Page 47: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

MVC フレームワークを Wicket に固定していた

Wicket

Controller

View

Bad!!

進化し続けるフロント技術や これに伴う要件に応えるため せめて View は柔軟に 変更可能であるべき

Better

Page 48: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

事実として View を取りまく フレームワークは 変化し続けている

Page 49: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Servlet + JSP Struts + JSP Struts + Velocity Struts2 + FreeMaker Spring MVC + FreeMaker Spring MVC + Thymeleaf

Page 50: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ.1• 適用する MVC Framework を制限してしまった

• 制限して、同じものを繰り返し使わせることで確実にナレッジは蓄積しやすくなるが、要件に応えられないのであれば意味は無い

• あるべき姿は柔軟に選択可能な状態 • そのうえで選択肢となりうるフレームワークの特徴やメリット/デメリット/ナレッジなどが事前に展開されているとより良い

Page 51: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

Page 52: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用

InHouse

Service DB Access

Business Requirements

Page 53: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用

InHouse

Service DB Access

Business Requirements

Bad!!

Page 54: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

InHouse

Service

Spring Framework

Aspect J

Wicket

Controller

View DB Access

Business Requirements

Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用

InHouse

Service DB Access

Business Requirements

Bad!!

コンポーネントごとの DI を意識した上で 適切に責務分割を行い 疎な状態を維持する Better

Page 55: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

適切な責務分割とは?

Page 56: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring には 都合の良いことに各種コンポーネント アノテーションが 用意されている

Page 57: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

@Controller @Service @Repository @Component @Configuration etc...

Page 58: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

@Controller

@Service

@Repository

@Component

@Configuration

Page 59: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

これに倣うだけで 適切に責務は 分割される

Page 60: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

本当に適切? 基準は?

Page 61: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

テストがしやすいか

Page 62: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ.2• DI を無視して適切な責務分割を行っていなかった

• テンプレートパターンは有用なデザインパターンのひとつだが、どんな規模でも有効に作用するとは限らない

• 適切な責務分割を意識する • Spring の場合、都合の良いことに、責務を 各種コンポーネントアノテーションで定義しておりこれに倣うだけで適切な分割が働く

Page 63: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.1 GA ベース

● MVC フレームワークには Struts2 を採用

● サービスレイヤ以下を自社開発 • テンプレートパターンによる実装 • bean 定義でサービス同士を相互に呼び出せるような仕組みを実装

第2弾

Page 64: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

社内標準フレームワーク開発● Spring Framework 3.1 GA ベース

● MVC フレームワークには Struts2 を採用

● サービスレイヤ以下を自社開発 • テンプレートパターンによる実装 • bean 定義でサービス同士を相互に呼び出せるような仕組みを実装

Good!

Bad!!

Bad!!

第2弾

Page 65: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

良くなかった ポイントはほぼ同じ

なので 割愛

Page 66: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

その後

Page 67: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

転職して 新たな環境へと移り...

Page 68: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

実はしばらくの間Spring を適用する

機会に恵まれなかった

Page 69: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

そんな中 目にしてきたものは

Page 70: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

オレオレ フレームワーク

Page 71: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

リクルートでの開発事情● ニジボックス (2012-2013)

• カードエンジンと呼ばれるソシャゲ開発用のプロジェクトテンプレートが用意されていた

• PHP によるオレオレフレームワーク

● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースのオレオレフレームワーク

• 前職で作ってきたものと同じ臭いを感じた

Page 72: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

リクルートでの開発事情● ニジボックス (2012-2013)

• カードエンジンと呼ばれるソシャゲ開発用のプロジェクトテンプレートが用意されていた

• PHP によるオレオレフレームワーク

● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースのオレオレフレームワーク

• 前職で作ってきたものと同じ臭いを感じた

Bad!!

Page 73: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

リクルートでの開発事情● ニジボックス (2012-2013)

• カードエンジンと呼ばれるソシャゲ開発用のプロジェクトテンプレートが用意されていた

• PHP によるオレオレフレームワーク

● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースのオレオレフレームワーク

• 前職で作ってきたものと同じ臭いを感じた

Bad!!

Bad!!

Page 74: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

中途入社したわたしは 非常に苦労しました

Page 75: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

オレオレ フレームワークに

ありがちな多くの事象が 現場で発生していた

Page 76: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

整備不足の ドキュメント

(ネットで引いても もちろん見つからない)

Page 77: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

フレームワークに 縛られるインフラ

(セキュリティリスクに対するコスト増を招く)

Page 78: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

使用可能な 技術が限定的

(新たな技術を取り入れるにはトンチが必要)

Page 79: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

フレームワークのクセ を把握していることが

仕事になる (クセというか不具合というか...)

Page 80: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

なんでこんなことすら できないの!??

Page 81: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring なら30分で 解決するのに...!

Page 82: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

そんなものに あふれていた

Page 83: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

こう 思うに至る

Page 84: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

  オレオレ

フレームワーク  

ダメ。ゼッタイ。

Page 85: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

やめましょう

Page 86: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ収集期      まとめ

● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 87: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ収集期      まとめ

● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

過度な独自仕様の作りこみや オレオレフレームワーク の開発を行ってはいけない

Page 88: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

株式会社リクルートライフスタイル 菊池 陽一

Page 89: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

株式会社リクルートライフスタイル 菊池 陽一

Page 90: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索

2007.11Spring Framework 2.5

2009.12Spring Framework 3.0

2011.12Spring Framework 3.1

2013.12 Spring Framework 4.0

略歴

Page 91: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

2007.04中堅 SIer 新卒入社 2009.12社内標準フレームワーク開発Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索

2007.11Spring Framework 2.5

2009.12Spring Framework 3.0

2011.12Spring Framework 3.1

2013.12 Spring Framework 4.0

略歴

ベタープラクティス実践期

Page 92: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記

Page 93: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記

Page 94: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記?

Page 95: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記エンドレスに改善しつづけたいので

あえて「ベスト」という言葉は使用していません

Page 96: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

これまで集めた バッドノウハウを もとに より良い

使い方を考えてみる

Page 97: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

集まったバッドノウハウたち● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 98: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

集まったバッドノウハウたち● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 99: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

Page 100: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

どうするべきか

Page 101: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

どうするべきか

>> Spring では、HTML や JSP などの他、レスポンス可能なあらゆるものをController が返却できることを意識する

Page 102: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

より具体的には...

Page 103: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

より具体的には...

>> Spring MVC を採用し、さまざまな Viewへ対応可能にしておく。RestController を使用してフロントを完全分離する (バックエンドシステムの API 化を促進する)

Page 104: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

@Controller @RequestMapping("employees")public class EmployeeController { @RequestMapping(produces = "text/html") public String getHtml() { return "employee"; } @RequestMapping(produces = "application/json", consumes = ..) @ResponseBody public String getJson() { return new Employee("Yoichi", "RLS", 30); }

@RequestMapping(produces = "application/xml", consumes = ..) @ResponseBody public String getXml() { return new Employee("Yoichi", "RLS", 30); } }

Page 105: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

@Controller @RequestMapping("employees")public class EmployeeController { @RequestMapping(produces = "text/html") public String getHtml() { return "employee"; } @RequestMapping(produces = "application/json", consumes = ..) @ResponseBody public String getJson() { return new Employee("Yoichi", "RLS", 30); }

@RequestMapping(produces = "application/xml", consumes = ..) @ResponseBody public String getXml() { return new Employee("Yoichi", "RLS", 30); } }

扱うデータは同じ

Page 106: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

@Controller @RequestMapping("employees")public class EmployeeController { @RequestMapping(produces = "text/html") public String getHtml() { return "employee"; } @RequestMapping(produces = "application/json", consumes = ..) @ResponseBody public String getJson() { return new Employee("Yoichi", "RLS", 30); }

@RequestMapping(produces = "application/xml", consumes = ..) @ResponseBody public String getXml() { return new Employee("Yoichi", "RLS", 30); } }

扱うデータは同じ

表現の方法が異なる

Page 107: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

どうするべきか

>> Spring では、HTML や JSP などの他、レスポンス可能なあらゆるものをController が返却できることを意識する

Page 108: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

どうするべきか

>> Spring では、HTML や JSP などの他、レスポンス可能なあらゆるものをController が返却できることを意識する

>> Spring では、RDB の他、スキーマレスDB、ファイル、API、などあらゆる外部リソースを永続化レイヤで扱うことを意識する

Page 109: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

より具体的には...

>> Spring MVC を採用し、さまざまな Viewへ対応可能にしておく。RestControllerを使用してフロントを完全分離する (バックエンドシステムの API 化を促進する)

Page 110: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

より具体的には...

>> Spring MVC を採用し、さまざまな Viewへ対応可能にしておく。RestControllerを使用してフロントを完全分離する (バックエンドシステムの API 化を促進する)

>> Repository レイヤを抽象化してどのような外部リソースへも切替可能にしておく

Page 111: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

public interface EmployeeRepository { Employee getItem();}

@Repository @Primary public class EmployeeJdbcRepository implements EmployeeRepos.. {}@Repository public class EmployeeMongoRepository implements EmployeeRep.. {}

@Service public class EmployeeService { @Autowired public EmployeeService(EmployeeRepository employeeRepository) {} }

Page 112: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

public interface EmployeeRepository { Employee getItem();}

@Repository @Primary public class EmployeeJdbcRepository implements EmployeeRepos.. {}@Repository public class EmployeeMongoRepository implements EmployeeRep.. {}

@Service public class EmployeeService { @Autowired public EmployeeService(EmployeeRepository employeeRepository) {} }

Serviceが見るのは interface

Page 113: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

public interface EmployeeRepository { Employee getItem();}

@Repository @Primary public class EmployeeJdbcRepository implements EmployeeRepos.. {}@Repository public class EmployeeMongoRepository implements EmployeeRep.. {}

@Service public class EmployeeService { @Autowired public EmployeeService(EmployeeRepository employeeRepository) {} }

Serviceが見るのは interface

Primary 側が DI される @Bean + @ConditionalOn 等の利用でより柔軟に

Page 114: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

集まったバッドノウハウたち● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 115: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

Page 116: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

どうするべきか

Page 117: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

どうするべきか

>> Spring のレイヤデザインに従い、適切に責務分割を行うことを意識して、各レイヤが疎な状態を維持できるように注意して設計・実装を行う

Page 118: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

より具体的には...

Page 119: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

より具体的には...

>> @Controller → URL と View、Service の紐付けを表現

Page 120: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

より具体的には...

>> @Controller → URL と View、Service の紐付けを表現

>> @Service → 業務プロセスを表現

Page 121: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

より具体的には...

>> @Controller → URL と View、Service の紐付けを表現

>> @Service → 業務プロセスを表現

>> @Repository → 外部リソースアクセスを表現

Page 122: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Controller

Service

Repository

Template

Spring Framework

Aspect J

View

@Controller

@Service

@Repository

@Component

@Configuration

Page 123: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

集まったバッドノウハウたち● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 124: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 125: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

どうするべきか

Page 126: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

どうするべきか

>> Spring をなるべくそのまま使いましょうこれに限ります

Page 127: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

より具体的には...

Page 128: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

より具体的には...

>> Spring をベースにライブラリを追加していく形で製品を作り上げる

Page 129: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

作り方に制限が加わるような独自の作り込みをおこなってはいけない

より具体的には...

>> Spring をベースにライブラリを追加していく形で製品を作り上げる

>> 独自の作りこみを行う場合は、コア機能に影響を与えないよう着脱可能な実装を意識する(プラグイン/アドオンのようなイメージで)

Page 130: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

@Aspect @Component public class ResponseWrapperAdvice { @Around("execution(* com.yo1000.controller.*.*(..)) && " + "@annotation(..annotation.RequestMapping)") public Object appendPrefix(ProceedingJoinPoint joinPoint) throws .. { Object ret = joinPoint.proceed(); if (ret instanceof Employee) { Employee emp = (Employee) ret; emp.setName(emp.isMale() ? ("Mr. " + emp.getName()) : "Ms. " + emp.getName()); } return ret; } }

作り方に制限が加わるような独自の作り込みをおこなってはいけない

Page 131: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

@Aspect @Component public class ResponseWrapperAdvice { @Around("execution(* com.yo1000.controller.*.*(..)) && " + "@annotation(..annotation.RequestMapping)") public Object appendPrefix(ProceedingJoinPoint joinPoint) throws .. { Object ret = joinPoint.proceed(); if (ret instanceof Employee) { Employee emp = (Employee) ret; emp.setName(emp.isMale() ? ("Mr. " + emp.getName()) : "Ms. " + emp.getName()); } return ret; } }

作り方に制限が加わるような独自の作り込みをおこなってはいけない

AOP を使用

Page 132: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

@Aspect @Component public class ResponseWrapperAdvice { @Around("execution(* com.yo1000.controller.*.*(..)) && " + "@annotation(..annotation.RequestMapping)") public Object appendPrefix(ProceedingJoinPoint joinPoint) throws .. { Object ret = joinPoint.proceed(); if (ret instanceof Employee) { Employee emp = (Employee) ret; emp.setName(emp.isMale() ? ("Mr. " + emp.getName()) : "Ms. " + emp.getName()); } return ret; } }

作り方に制限が加わるような独自の作り込みをおこなってはいけない

AOP を使用

指定したメソッドパターン、アノテーションパターンの処理に割り込む

Page 133: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記       まとめ

● Spring MVC を使用した上で Microservices のような設計を意識してシステム間依存をなるべく疎な状態に保つ (API 化、Repository の抽象化)

● Spring のレイヤデザイン (Controller/Service/Repository/Template) に従った実装を意識する

● 独自の作り込みが発生する場合は、プラグイン的な実装を心がける (Bad: 継承/Better: AOP)

Page 134: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記       まとめ

● Spring MVC を使用した上で Microservices のような設計を意識してシステム間依存をなるべく疎な状態に保つ (Repository の抽象化)

● Spring のレイヤデザイン (Controller/Service/Repository/Template) をに従う

● 独自の作り込みが発生する場合は、プラグイン的な実装を心がける (Bad: 継承/Better: AOP)

SpringFramework の理解を深めましょう

Page 135: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

株式会社リクルートライフスタイル 菊池 陽一

Page 136: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

おわりに

Page 137: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

バッドノウハウ収集期      まとめ

● Spring を使用する上で、周辺アーキテクチャに縛りを加えてはいけない

● Spring のレイヤデザイン (Controller/Service/Repository/Template) を無視してはいけない

● 作り方に制限が加わるような独自の作り込みをおこなってはいけない

過度な独自仕様の作りこみや オレオレフレームワーク の開発を行ってはいけない

Page 138: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

ベタープラクティス実践記       まとめ

● Spring MVC を使用した上で Microservices のような設計を意識してシステム間依存をなるべく疎な状態に保つ (Repository の抽象化)

● Spring のレイヤデザイン (Controller/Service/Repository/Template) をに従う

● 独自の作り込みが発生する場合は、プラグイン的な実装を心がける (Bad: 継承/Better: AOP)

SpringFramework の理解を深めましょう

Page 139: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

おわりに

Page 140: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

最終的な着地としては、わりと一般的なお話になってしまいました。ですが、Springは進化を続けています。今回お話した内容もいつ覆るかはわかりません。

わたしも5年前にSpringに触れ始めた頃には、現在のSpringBootのような非常に簡単かつパワフルな機能が出てくるとは思ってもいませんでした。そういう意味でも、わたし自身もSpringの進化を引き続き追いかけて行きたいと思います!

Page 141: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

Appendix

Page 142: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

vis• KPI VISualizer • システムに、時間と値の二軸表現可能な結果を返す SQL を登録することで、これを動的にグラフ化して表示してくれるもの。

• Spring Boot を使用したプロジェクト。 • https://github.com/yo1000/vis

Page 143: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Page 144: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

bluefairy• Docker Web Client • Docker Remote API をプロパティに設定して起動すると、Docker イメージの閲覧や、コンテナの起動が行える Web Client。

• Spring Boot を使用したプロジェクト。 • https://github.com/yo1000/bluefairy

Page 145: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Page 146: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

dbspock• spock ライクに DBUnit を使用できるようにしたライブラリ

• Groovy を使用したプロジェクト。 • https://github.com/yo1000/dbspock

Page 147: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

<dependencies> <dependency> <groupId>com.yo1000</groupId> <artifactId>dbspock</artifactId> <version>0.1.2.RELEASE</version> </dependency> </dependencies> <repositories> <repository> <id>com.yo1000</id> <name>yo1000 maven repository</name> <url>http://yo1000.github.io/maven/</url> </repository> </repositories>

dbspock

Page 148: Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス

class RepositorySpec extends Specification {

def "DBSpockTest"() {

setup:

def tester = new DataSourceDatabaseTester(dataSource)

def data = {

_cols_ 'SHOP_ID' | 'SHOP_NAME' | 'SHOP_CREATED'

shop 'SP-1' | 'BURGER KING' | '2015-04-01'

shop 'SP-2' | 'RANDYS DONUTS' | '2015-04-01'

}

def flatxml = {

data.call()

data.build()

}

data.delegate = new SpockLikeFlatXmlBuilder()

tester.dataSet = new FlatXmlDataSet(new StringReader(flatxml.call()))

tester.onSetup()

expect:

...

dbspock