Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
JSUG 2015
Spring in Summer 夏なのにSpring 菊池 陽一
菊池 陽一
Github: yo1000
hatena: Yoichi-KIKUCHI
Spring 歴: 5年
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との...
みなさん
Spring どんなふうに
使っていますか?
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
• 社内標準
• 受託案件
• 自社プロダクト
• ベンダプロダクト
• 日曜プロダクト
なんにでも
適用できますよね
(とくにバックエンドシステムでは)
非常に多機能かつ
柔軟に設計されている
Spring ならでは
Java をメインに
システム構築して
いるのであれば
Spring を
選ばない手はない
むしろ
Spring に非ずんば
Java に非ず
現在 それくらい
採用の広がっている
実感があります
たとえば Atlassian
Confluence では
ランタイムオブジェクトの管理に
Spring を使用している
たとえば JetBrains
TeamCity では
独自拡張した Spring
コンテナを使用している
たとえば JetBrains
サードパーティ製

フルスタックフレームワークで
IntelliJ のデフォルトサポートが
あるのは Spring のみ!
現在 国外のみならず
国内でも広く認知され
採用に至っている
そんな Spring ですが
実際の業務適用に
ついてはというと...
いままさに仕掛中!とか

これからやりたい!とか
そこで これまでの
5年すこしで感じた
Spring についての
あれこれをご紹介
株式会社リクルートライフスタイル
菊池 陽一
株式会社リクルートライフスタイル
菊池 陽一
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との出会い
2011.04
社内標準フレームワーク更新
2012.08
リクルート入社 (ニジボックス)
2013.0...
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との出会い
2011.04
社内標準フレームワーク更新
2012.08
リクルート入社 (ニジボックス)
2013.0...
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との出会い
2011.04
社内標準フレームワーク更新
2012.08
リクルート入社 (ニジボックス)
2013.0...
バッドノウハウ収集期
当時そんなつもりは全くありませんでしたが
振り返ってみるとバッドノウハウが多かった...
社内標準フレームワーク開発
● Spring Framework 3.0 GA ベース
● MVC フレームワークには Wicket を採用
● サービスレイヤ以下を自社開発
• ビジネスプロセスをテンプレートパターン

により実装
• bea...
社内標準フレームワーク開発
● Spring Framework 3.0 GA ベース
● MVC フレームワークには Wicket を採用
● サービスレイヤ以下を自社開発
• ビジネスプロセスをテンプレートパターン

により実装
• bea...
社内標準フレームワーク開発
● Spring Framework 3.0 GA ベース
● MVC フレームワークには Wicket を採用
● サービスレイヤ以下を自社開発
• ビジネスプロセスをテンプレートパターン

により実装
• bea...
社内標準フレームワーク開発
● Spring Framework 3.0 GA ベース
● MVC フレームワークには Wicket を採用
● サービスレイヤ以下を自社開発
• ビジネスプロセスをテンプレートパターン

により実装
• bea...
何が良くなかったのか
一般的な
Spring Project
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Request
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
Request
社内標準としていた
フレームワーク
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
MVC フレームワークを
Wicket に固定して...
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
MVC フレームワークを
Wicket に固定して...
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
MVC フレームワークを
Wicket に固定して...
事実として
View を取りまく
フレームワークは
変化し続けている
Servlet + JSP
Struts + JSP
Struts + Velocity
Struts2 + FreeMaker
Spring MVC + FreeMaker
Spring MVC + Thymeleaf
バッドノウハウ.1
• 適用する MVC Framework を制限してしまった
• 制限して、同じものを繰り返し使わせることで

確実にナレッジは蓄積しやすくなるが、

要件に応えられないのであれば意味は無い
• あるべき姿は柔軟に選択可能な...
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
Service レイヤ以降の本来の構成を無視して
...
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
Service レイヤ以降の本来の構成を無視して
...
InHouse
Service
Spring Framework
Aspect J
Wicket
Controller
View
DB Access
Business
Requirements
Service レイヤ以降の本来の構成を無視して
...
適切な責務分割とは?
Spring には
都合の良いことに

各種コンポーネント
アノテーションが
用意されている
@Controller
@Service
@Repository
@Component
@Configuration
etc...
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
@Controller
@Service
@Repository@Component
@Configura...
これに倣うだけで
適切に責務は
分割される
本当に適切?
基準は?
テストがしやすいか
バッドノウハウ.2
• DI を無視して適切な責務分割を行っていなかった
• テンプレートパターンは有用な

デザインパターンのひとつだが、

どんな規模でも有効に作用するとは限らない
• 適切な責務分割を意識する
• Spring の場合、都...
社内標準フレームワーク開発
● Spring Framework 3.1 GA ベース
● MVC フレームワークには Struts2 を採用
● サービスレイヤ以下を自社開発
• テンプレートパターンによる実装
• bean 定義でサービス同...
社内標準フレームワーク開発
● Spring Framework 3.1 GA ベース
● MVC フレームワークには Struts2 を採用
● サービスレイヤ以下を自社開発
• テンプレートパターンによる実装
• bean 定義でサービス同...
良くなかった
ポイントはほぼ同じ
なので 割愛
その後
転職して
新たな環境へと移り...
実はしばらくの間

Spring を適用する
機会に恵まれなかった
そんな中
目にしてきたものは
オレオレ
フレームワーク
リクルートでの開発事情
● ニジボックス (2012-2013)
• カードエンジンと呼ばれるソシャゲ開発用の

プロジェクトテンプレートが用意されていた
• PHP によるオレオレフレームワーク
● リクルートライフスタイル (2013-)
...
リクルートでの開発事情
● ニジボックス (2012-2013)
• カードエンジンと呼ばれるソシャゲ開発用の

プロジェクトテンプレートが用意されていた
• PHP によるオレオレフレームワーク
● リクルートライフスタイル (2013-)
...
リクルートでの開発事情
● ニジボックス (2012-2013)
• カードエンジンと呼ばれるソシャゲ開発用の

プロジェクトテンプレートが用意されていた
• PHP によるオレオレフレームワーク
● リクルートライフスタイル (2013-)
...
中途入社したわたしは
非常に苦労しました
オレオレ
フレームワークに
ありがちな多くの事象が
現場で発生していた
整備不足の
ドキュメント
(ネットで引いても もちろん見つからない)
フレームワークに
縛られるインフラ
(セキュリティリスクに対するコスト増を招く)
使用可能な
技術が限定的
(新たな技術を取り入れるにはトンチが必要)
フレームワークのクセ
を把握していることが
仕事になる
(クセというか不具合というか...)
なんでこんなことすら
できないの!??
Spring なら30分で
解決するのに...!
そんなものに
あふれていた
こう 思うに至る
  オレオレ
フレームワーク 
ダメ。ゼッタイ。
やめましょう
バッドノウハウ収集期

      まとめ
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template)...
バッドノウハウ収集期

      まとめ
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template)...
株式会社リクルートライフスタイル
菊池 陽一
株式会社リクルートライフスタイル
菊池 陽一
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との出会い
2011.04
社内標準フレームワーク更新
2012.08
リクルート入社 (ニジボックス)
2013.0...
2007.04

中堅 SIer 新卒入社
2009.12

社内標準フレームワーク開発

Spring Framework との出会い
2011.04
社内標準フレームワーク更新
2012.08
リクルート入社 (ニジボックス)
2013.0...
ベタープラクティス実践記
ベタープラクティス実践記
ベタープラクティス実践記
?
ベタープラクティス実践記
エンドレスに改善しつづけたいので
あえて「ベスト」という言葉は使用していません
これまで集めた
バッドノウハウを
もとに より良い
使い方を考えてみる
集まったバッドノウハウたち
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはい...
集まったバッドノウハウたち
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはい...
Spring を使用する上で、

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

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

周辺アーキテクチャに縛りを加えてはいけない
どうするべきか
>> Spring では、HTML や JSP などの他、

レスポンス可能なあらゆるものを

Controller が返却できることを意識する
Spring を使用する上で、

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

周辺アーキテクチャに縛りを加えてはいけない
より具体的には...
>> Spring MVC を採用し、さまざまな View
へ対応可能にしておく。RestController
を使用してフロントを完全分離する...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
@Controller

@RequestMapping("employees")

public class EmployeeController {

@Requ...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
@Controller

@RequestMapping("employees")

public class EmployeeController {

@Requ...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
@Controller

@RequestMapping("employees")

public class EmployeeController {

@Requ...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
どうするべきか
>> Spring では、HTML や JSP などの他、

レスポンス可能なあらゆるものを

Controller が返却できることを意識する
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
どうするべきか
>> Spring では、HTML や JSP などの他、

レスポンス可能なあらゆるものを

Controller が返却できることを意識する
>>...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
より具体的には...
>> Spring MVC を採用し、さまざまな View
へ対応可能にしておく。RestController
を使用してフロントを完全分離する...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
より具体的には...
>> Spring MVC を採用し、さまざまな View
へ対応可能にしておく。RestController
を使用してフロントを完全分離する...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
public interface EmployeeRepository {

Employee getItem();

}

@Repository @Primary...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
public interface EmployeeRepository {

Employee getItem();

}

@Repository @Primary...
Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
public interface EmployeeRepository {

Employee getItem();

}

@Repository @Primary...
集まったバッドノウハウたち
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはい...
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
どうするべきか
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
どうするべきか
>> Spring のレイヤデザインに従い、

適切に責務分割を行うことを意識して、

各...
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
より具体的には...
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
より具体的には...
>> @Controller
→ URL と View、Service の紐付けを表現
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
より具体的には...
>> @Controller
→ URL と View、Service の紐付けを表...
Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはいけない
より具体的には...
>> @Controller
→ URL と View、Service の紐付けを表...
Controller
Service
Repository
Template
Spring Framework
Aspect J
View
@Controller
@Service
@Repository@Component
@Configura...
集まったバッドノウハウたち
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template) を無視してはい...
作り方に制限が加わるような

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

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

独自の作り込みをおこなってはいけない
どうするべきか
>> Spring をなるべくそのまま使いましょう

これに限ります
作り方に制限が加わるような

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

独自の作り込みをおこなってはいけない
より具体的には...
>> Spring をベースにライブラリを

追加していく形で製品を作り上げる
作り方に制限が加わるような

独自の作り込みをおこなってはいけない
より具体的には...
>> Spring をベースにライブラリを

追加していく形で製品を作り上げる
>> 独自の作りこみを行う場合は、

コア機能に影響を与えないよう

着脱...
@Aspect @Component

public class ResponseWrapperAdvice {

@Around("execution(* com.yo1000.controller.*.*(..)) && "

+ "@an...
@Aspect @Component

public class ResponseWrapperAdvice {

@Around("execution(* com.yo1000.controller.*.*(..)) && "

+ "@an...
@Aspect @Component

public class ResponseWrapperAdvice {

@Around("execution(* com.yo1000.controller.*.*(..)) && "

+ "@an...
ベタープラクティス実践記

      まとめ
● Spring MVC を使用した上で Microservices のよ
うな設計を意識してシステム間依存をなるべく疎な
状態に保つ (API 化、Repository の抽象化)
● Spri...
ベタープラクティス実践記

      まとめ
● Spring MVC を使用した上で Microservices のよ
うな設計を意識してシステム間依存をなるべく疎な
状態に保つ (Repository の抽象化)
● Spring のレイ...
株式会社リクルートライフスタイル
菊池 陽一
おわりに
バッドノウハウ収集期

      まとめ
● Spring を使用する上で、

周辺アーキテクチャに縛りを加えてはいけない
● Spring のレイヤデザイン (Controller/Service/
Repository/Template)...
ベタープラクティス実践記

      まとめ
● Spring MVC を使用した上で Microservices のよ
うな設計を意識してシステム間依存をなるべく疎な
状態に保つ (Repository の抽象化)
● Spring のレイ...
おわりに
最終的な着地としては、わりと一般的なお話になってしまい
ました。ですが、Springは進化を続けています。今回お話し
た内容もいつ覆るかはわかりません。

わたしも5年前にSpringに触れ始めた頃には、現在の
SpringBootのような非常...
Appendix
vis
• KPI VISualizer
• システムに、時間と値の二軸表現可能な結果を返す
SQL を登録することで、これを動的にグラフ化し
て表示してくれるもの。
• Spring Boot を使用したプロジェクト。
• https://g...
bluefairy
• Docker Web Client
• Docker Remote API をプロパティに設定して起動
すると、Docker イメージの閲覧や、コンテナの起
動が行える Web Client。
• Spring Boot...
dbspock
• spock ライクに DBUnit を使用できるようにした
ライブラリ
• Groovy を使用したプロジェクト。
• https://github.com/yo1000/dbspock
<dependencies>
<dependency>
<groupId>com.yo1000</groupId>
<artifactId>dbspock</artifactId>
<version>0.1.2.RELEASE</version...
class	
 RepositorySpec	
 extends	
 Specification	
 {	
 
	
 	
 	
 	
 def	
 "DBSpockTest"()	
 {	
 
	
 	
 	
 	
 	
 	
 	
 	
 s...
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Upcoming SlideShare
Loading in …5
×

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

7,478 views

Published on

JSUG 2015 Summer での発表資料を公開します

Published in: Technology
  • Be the first to comment

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

  1. 1. JSUG 2015 Spring in Summer 夏なのにSpring 菊池 陽一
  2. 2. 菊池 陽一 Github: yo1000 hatena: Yoichi-KIKUCHI Spring 歴: 5年 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring 適用を模索
  3. 3. みなさん
  4. 4. Spring どんなふうに 使っていますか?
  5. 5. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  6. 6. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  7. 7. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  8. 8. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  9. 9. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  10. 10. • 社内標準 • 受託案件 • 自社プロダクト • ベンダプロダクト • 日曜プロダクト
  11. 11. なんにでも 適用できますよね (とくにバックエンドシステムでは)
  12. 12. 非常に多機能かつ 柔軟に設計されている Spring ならでは
  13. 13. Java をメインに システム構築して いるのであれば
  14. 14. Spring を 選ばない手はない
  15. 15. むしろ
  16. 16. Spring に非ずんば Java に非ず
  17. 17. 現在 それくらい 採用の広がっている 実感があります
  18. 18. たとえば Atlassian Confluence では ランタイムオブジェクトの管理に Spring を使用している
  19. 19. たとえば JetBrains TeamCity では 独自拡張した Spring コンテナを使用している
  20. 20. たとえば JetBrains サードパーティ製
 フルスタックフレームワークで IntelliJ のデフォルトサポートが あるのは Spring のみ!
  21. 21. 現在 国外のみならず 国内でも広く認知され 採用に至っている
  22. 22. そんな Spring ですが 実際の業務適用に ついてはというと...
  23. 23. いままさに仕掛中!とか
 これからやりたい!とか
  24. 24. そこで これまでの 5年すこしで感じた Spring についての あれこれをご紹介
  25. 25. 株式会社リクルートライフスタイル 菊池 陽一
  26. 26. 株式会社リクルートライフスタイル 菊池 陽一
  27. 27. 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索 2007.11
 Spring Framework 2.5 2009.12
 Spring Framework 3.0 2011.12
 Spring Framework 3.1 2013.12 Spring Framework 4.0 略歴
  28. 28. 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索 2007.11
 Spring Framework 2.5 2009.12
 Spring Framework 3.0 2011.12
 Spring Framework 3.1 2013.12 Spring Framework 4.0 略歴 バッドノウハウ収集期
  29. 29. 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索 2007.11
 Spring Framework 2.5 2009.12
 Spring Framework 3.0 2011.12
 Spring Framework 3.1 2013.12 Spring Framework 4.0 略歴 ベタープラクティス実践期
  30. 30. バッドノウハウ収集期 当時そんなつもりは全くありませんでしたが 振り返ってみるとバッドノウハウが多かった...
  31. 31. 社内標準フレームワーク開発 ● Spring Framework 3.0 GA ベース ● MVC フレームワークには Wicket を採用 ● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターン
 により実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを作りこんでいた
  32. 32. 社内標準フレームワーク開発 ● Spring Framework 3.0 GA ベース ● MVC フレームワークには Wicket を採用 ● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターン
 により実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを作りこんでいた Good!
  33. 33. 社内標準フレームワーク開発 ● Spring Framework 3.0 GA ベース ● MVC フレームワークには Wicket を採用 ● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターン
 により実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを作りこんでいた Good! Bad!!
  34. 34. 社内標準フレームワーク開発 ● Spring Framework 3.0 GA ベース ● MVC フレームワークには Wicket を採用 ● サービスレイヤ以下を自社開発 • ビジネスプロセスをテンプレートパターン
 により実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを作りこんでいた Good! Bad!! Bad!!
  35. 35. 何が良くなかったのか
  36. 36. 一般的な Spring Project
  37. 37. Controller Service Repository Template Spring Framework Aspect J View
  38. 38. Controller Service Repository Template Spring Framework Aspect J View
  39. 39. Controller Service Repository Template Spring Framework Aspect J View Request
  40. 40. Controller Service Repository Template Spring Framework Aspect J View
  41. 41. Controller Service Repository Template Spring Framework Aspect J View
  42. 42. Controller Service Repository Template Spring Framework Aspect J View Request
  43. 43. 社内標準としていた フレームワーク
  44. 44. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements
  45. 45. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements MVC フレームワークを Wicket に固定していた Wicket Controller View
  46. 46. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements MVC フレームワークを Wicket に固定していた Wicket Controller View Bad!!
  47. 47. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements MVC フレームワークを Wicket に固定していた Wicket Controller View Bad!! 進化し続けるフロント技術や これに伴う要件に応えるため せめて View は柔軟に 変更可能であるべき Better
  48. 48. 事実として View を取りまく フレームワークは 変化し続けている
  49. 49. Servlet + JSP Struts + JSP Struts + Velocity Struts2 + FreeMaker Spring MVC + FreeMaker Spring MVC + Thymeleaf
  50. 50. バッドノウハウ.1 • 適用する MVC Framework を制限してしまった • 制限して、同じものを繰り返し使わせることで
 確実にナレッジは蓄積しやすくなるが、
 要件に応えられないのであれば意味は無い • あるべき姿は柔軟に選択可能な状態 • そのうえで選択肢となりうるフレームワークの
 特徴やメリット/デメリット/ナレッジなどが
 事前に展開されているとより良い
  51. 51. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements
  52. 52. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用 InHouse Service DB Access Business Requirements
  53. 53. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用 InHouse Service DB Access Business Requirements Bad!!
  54. 54. InHouse Service Spring Framework Aspect J Wicket Controller View DB Access Business Requirements Service レイヤ以降の本来の構成を無視して テンプレートパターンを適用 InHouse Service DB Access Business Requirements Bad!! コンポーネントごとの DI を意識した上で 適切に責務分割を行い 疎な状態を維持する Better
  55. 55. 適切な責務分割とは?
  56. 56. Spring には 都合の良いことに
 各種コンポーネント アノテーションが 用意されている
  57. 57. @Controller @Service @Repository @Component @Configuration etc...
  58. 58. Controller Service Repository Template Spring Framework Aspect J View @Controller @Service @Repository@Component @Configuration
  59. 59. これに倣うだけで 適切に責務は 分割される
  60. 60. 本当に適切? 基準は?
  61. 61. テストがしやすいか
  62. 62. バッドノウハウ.2 • DI を無視して適切な責務分割を行っていなかった • テンプレートパターンは有用な
 デザインパターンのひとつだが、
 どんな規模でも有効に作用するとは限らない • 適切な責務分割を意識する • Spring の場合、都合の良いことに、責務を
 各種コンポーネントアノテーションで
 定義しておりこれに倣うだけで適切な分割が働く
  63. 63. 社内標準フレームワーク開発 ● Spring Framework 3.1 GA ベース ● MVC フレームワークには Struts2 を採用 ● サービスレイヤ以下を自社開発 • テンプレートパターンによる実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを実装 第2弾
  64. 64. 社内標準フレームワーク開発 ● Spring Framework 3.1 GA ベース ● MVC フレームワークには Struts2 を採用 ● サービスレイヤ以下を自社開発 • テンプレートパターンによる実装 • bean 定義でサービス同士を相互に呼び出せるよ うな仕組みを実装 Good! Bad!! Bad!! 第2弾
  65. 65. 良くなかった ポイントはほぼ同じ なので 割愛
  66. 66. その後
  67. 67. 転職して 新たな環境へと移り...
  68. 68. 実はしばらくの間
 Spring を適用する 機会に恵まれなかった
  69. 69. そんな中 目にしてきたものは
  70. 70. オレオレ フレームワーク
  71. 71. リクルートでの開発事情 ● ニジボックス (2012-2013) • カードエンジンと呼ばれるソシャゲ開発用の
 プロジェクトテンプレートが用意されていた • PHP によるオレオレフレームワーク ● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースの
 オレオレフレームワーク • 前職で作ってきたものと同じ臭いを感じた
  72. 72. リクルートでの開発事情 ● ニジボックス (2012-2013) • カードエンジンと呼ばれるソシャゲ開発用の
 プロジェクトテンプレートが用意されていた • PHP によるオレオレフレームワーク ● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースの
 オレオレフレームワーク • 前職で作ってきたものと同じ臭いを感じた Bad!!
  73. 73. リクルートでの開発事情 ● ニジボックス (2012-2013) • カードエンジンと呼ばれるソシャゲ開発用の
 プロジェクトテンプレートが用意されていた • PHP によるオレオレフレームワーク ● リクルートライフスタイル (2013-) • R2 と呼ばれる Seasar2 + SAStruts ベースの
 オレオレフレームワーク • 前職で作ってきたものと同じ臭いを感じた Bad!! Bad!!
  74. 74. 中途入社したわたしは 非常に苦労しました
  75. 75. オレオレ フレームワークに ありがちな多くの事象が 現場で発生していた
  76. 76. 整備不足の ドキュメント (ネットで引いても もちろん見つからない)
  77. 77. フレームワークに 縛られるインフラ (セキュリティリスクに対するコスト増を招く)
  78. 78. 使用可能な 技術が限定的 (新たな技術を取り入れるにはトンチが必要)
  79. 79. フレームワークのクセ を把握していることが 仕事になる (クセというか不具合というか...)
  80. 80. なんでこんなことすら できないの!??
  81. 81. Spring なら30分で 解決するのに...!
  82. 82. そんなものに あふれていた
  83. 83. こう 思うに至る
  84. 84.   オレオレ フレームワーク  ダメ。ゼッタイ。
  85. 85. やめましょう
  86. 86. バッドノウハウ収集期
       まとめ ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  87. 87. バッドノウハウ収集期
       まとめ ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない 過度な独自仕様の作りこみや オレオレフレームワーク の開発を行ってはいけない
  88. 88. 株式会社リクルートライフスタイル 菊池 陽一
  89. 89. 株式会社リクルートライフスタイル 菊池 陽一
  90. 90. 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索 2007.11
 Spring Framework 2.5 2009.12
 Spring Framework 3.0 2011.12
 Spring Framework 3.1 2013.12 Spring Framework 4.0 略歴
  91. 91. 2007.04
 中堅 SIer 新卒入社 2009.12
 社内標準フレームワーク開発
 Spring Framework との出会い 2011.04 社内標準フレームワーク更新 2012.08 リクルート入社 (ニジボックス) 2013.07 リクルートライフスタイル転籍 MARQREL、HOTPEPPER で Spring の適用を模索 2007.11
 Spring Framework 2.5 2009.12
 Spring Framework 3.0 2011.12
 Spring Framework 3.1 2013.12 Spring Framework 4.0 略歴 ベタープラクティス実践期
  92. 92. ベタープラクティス実践記
  93. 93. ベタープラクティス実践記
  94. 94. ベタープラクティス実践記 ?
  95. 95. ベタープラクティス実践記 エンドレスに改善しつづけたいので あえて「ベスト」という言葉は使用していません
  96. 96. これまで集めた バッドノウハウを もとに より良い 使い方を考えてみる
  97. 97. 集まったバッドノウハウたち ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  98. 98. 集まったバッドノウハウたち ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  99. 99. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない
  100. 100. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない どうするべきか
  101. 101. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない どうするべきか >> Spring では、HTML や JSP などの他、
 レスポンス可能なあらゆるものを
 Controller が返却できることを意識する
  102. 102. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない より具体的には...
  103. 103. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない より具体的には... >> Spring MVC を採用し、さまざまな View へ対応可能にしておく。RestController を使用してフロントを完全分離する (バック エンドシステムの API 化を促進する)
  104. 104. 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); } }
  105. 105. 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); } } 扱うデータは同じ
  106. 106. 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); } } 扱うデータは同じ 表現の方法が異なる
  107. 107. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない どうするべきか >> Spring では、HTML や JSP などの他、
 レスポンス可能なあらゆるものを
 Controller が返却できることを意識する
  108. 108. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない どうするべきか >> Spring では、HTML や JSP などの他、
 レスポンス可能なあらゆるものを
 Controller が返却できることを意識する >> Spring では、RDB の他、スキーマレス DB、ファイル、API、などあらゆる外部リ ソースを永続化レイヤで扱うことを意識する
  109. 109. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない より具体的には... >> Spring MVC を採用し、さまざまな View へ対応可能にしておく。RestController を使用してフロントを完全分離する (バック エンドシステムの API 化を促進する)
  110. 110. Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない より具体的には... >> Spring MVC を採用し、さまざまな View へ対応可能にしておく。RestController を使用してフロントを完全分離する (バック エンドシステムの API 化を促進する) >> Repository レイヤを抽象化してどのよう な外部リソースへも切替可能にしておく
  111. 111. 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) {} }
  112. 112. 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
  113. 113. 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 等の利用でより柔軟に
  114. 114. 集まったバッドノウハウたち ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  115. 115. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない
  116. 116. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない どうするべきか
  117. 117. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない どうするべきか >> Spring のレイヤデザインに従い、
 適切に責務分割を行うことを意識して、
 各レイヤが疎な状態を維持できるように
 注意して設計・実装を行う

  118. 118. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない より具体的には...
  119. 119. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない より具体的には... >> @Controller → URL と View、Service の紐付けを表現
  120. 120. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない より具体的には... >> @Controller → URL と View、Service の紐付けを表現 >> @Service → 業務プロセスを表現
  121. 121. Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない より具体的には... >> @Controller → URL と View、Service の紐付けを表現 >> @Service → 業務プロセスを表現 >> @Repository → 外部リソースアクセスを表現
  122. 122. Controller Service Repository Template Spring Framework Aspect J View @Controller @Service @Repository@Component @Configuration
  123. 123. 集まったバッドノウハウたち ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  124. 124. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  125. 125. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない どうするべきか
  126. 126. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない どうするべきか >> Spring をなるべくそのまま使いましょう
 これに限ります
  127. 127. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない より具体的には...
  128. 128. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない より具体的には... >> Spring をベースにライブラリを
 追加していく形で製品を作り上げる
  129. 129. 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない より具体的には... >> Spring をベースにライブラリを
 追加していく形で製品を作り上げる >> 独自の作りこみを行う場合は、
 コア機能に影響を与えないよう
 着脱可能な実装を意識する
 (プラグイン/アドオンのようなイメージで)
  130. 130. @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; } } 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない
  131. 131. @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 を使用
  132. 132. @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 を使用 指定したメソッドパターン、
 アノテーションパターンの処理に割り込む
  133. 133. ベタープラクティス実践記
       まとめ ● Spring MVC を使用した上で Microservices のよ うな設計を意識してシステム間依存をなるべく疎な 状態に保つ (API 化、Repository の抽象化) ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) に従った実装を意識する ● 独自の作り込みが発生する場合は、プラグイン的な 実装を心がける (Bad: 継承/Better: AOP)
  134. 134. ベタープラクティス実践記
       まとめ ● Spring MVC を使用した上で Microservices のよ うな設計を意識してシステム間依存をなるべく疎な 状態に保つ (Repository の抽象化) ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) をに従う ● 独自の作り込みが発生する場合は、プラグイン的な 実装を心がける (Bad: 継承/Better: AOP) SpringFramework の理解を深めましょう
  135. 135. 株式会社リクルートライフスタイル 菊池 陽一
  136. 136. おわりに
  137. 137. バッドノウハウ収集期
       まとめ ● Spring を使用する上で、
 周辺アーキテクチャに縛りを加えてはいけない ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) を無視してはいけない ● 作り方に制限が加わるような
 独自の作り込みをおこなってはいけない 過度な独自仕様の作りこみや オレオレフレームワーク の開発を行ってはいけない
  138. 138. ベタープラクティス実践記
       まとめ ● Spring MVC を使用した上で Microservices のよ うな設計を意識してシステム間依存をなるべく疎な 状態に保つ (Repository の抽象化) ● Spring のレイヤデザイン (Controller/Service/ Repository/Template) をに従う ● 独自の作り込みが発生する場合は、プラグイン的な 実装を心がける (Bad: 継承/Better: AOP) SpringFramework の理解を深めましょう
  139. 139. おわりに
  140. 140. 最終的な着地としては、わりと一般的なお話になってしまい ました。ですが、Springは進化を続けています。今回お話し た内容もいつ覆るかはわかりません。 わたしも5年前にSpringに触れ始めた頃には、現在の SpringBootのような非常に簡単かつパワフルな機能が出てく るとは思ってもいませんでした。そういう意味でも、わたし 自身もSpringの進化を引き続き追いかけて行きたいと思いま す!
  141. 141. Appendix
  142. 142. vis • KPI VISualizer • システムに、時間と値の二軸表現可能な結果を返す SQL を登録することで、これを動的にグラフ化し て表示してくれるもの。 • Spring Boot を使用したプロジェクト。 • https://github.com/yo1000/vis
  143. 143. bluefairy • Docker Web Client • Docker Remote API をプロパティに設定して起動 すると、Docker イメージの閲覧や、コンテナの起 動が行える Web Client。 • Spring Boot を使用したプロジェクト。 • https://github.com/yo1000/bluefairy
  144. 144. dbspock • spock ライクに DBUnit を使用できるようにした ライブラリ • Groovy を使用したプロジェクト。 • https://github.com/yo1000/dbspock
  145. 145. <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
  146. 146. 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

×