2016/12/3 JJUG CCC 2016 fall 参加メモ

http://www.java-users.jp/ccc2016fall/

## SpringはどうやってDIしているのか
https://speakerdeck.com/bati11/springhadouyatutedisiteirufalseka-number-jjug-ccc

残念ながらちゃんと理解できたとは言い難いけど、SpringContainerの起動時にどんなことをしているのか何となくイメージが沸いて、とてもおもしろかった。

### Bean定義の登録
- AnnotationConfigApplicationContext
- @ConfigurationがついているクラスのBean定義をBeanDefinitionに変換
- AnnotatedBeanDefinitionReader
  + @Conditionalでスキップ可能
  + Beanの名前を決める
- DefaultListableBeanFactory
  + ConcurrentHashMapとしてインスタンス変数にBeanDefinitionが保存される
  + Bean生成処理を担う

### Component scan
- refresh
- BeanFactoryPostProcessor：フックして処理を挟める
- ConfigudationClassPostProcessor：component scan
  + classファイルを探す
  + バイトコードを解析
  + クラス名やAnnotationをチェック
  + Beanとなるクラスのみを選択してBeanDefinitionで表現
  - BeanDefinitionRegistryに登録

### Bean生成
- singletonスコープのbeanを生成
  + BeanDefinitionを取得（親Bean定義をマージ）
- getBean ⇒ キャッシュがあれば返す、なければ生成する
  + この中でインジェクション（Autowiredはコンストラクタインジェクション）
  + DefaultListableBeanFactoryでdependencyを解決する、その際にgetBeanが再帰的に呼ばれる
  + Reflecition(newInstance)でBeanを生成
- init-methodの呼び出し
- DefaultSingletonBeanRegistoryにキャッシュ
- ここまでで、ようやくAnnotationConfigApplicationContextのコンストラクタ（refresh()）が終了

### まとめ
- BeanFactory / BeanDefinitionReaderがあればDIはできる
  + DI以外をやるためには、ApplicationContextが必要
- DefaultListableBeanFactoryの仕事多すぎ！継承が複雑！（各インタフェースの役割を把握すると読みやすい）


## Javaエンジニアのためのブロックチェーン入門


### 話題になっている
- 来年が盛り上がりのピークになる？？
  + 仮想通貨取引所は淘汰されるはず（今までは免許がなくても参入でき参入障壁が低かった）
  + 2017/5から金融の法律が変わる
- メディアと金融業界が先に加熱
- 技術スタートアップが続々誕生している、ここから３年で淘汰が進むだろうが、残るものは確実にあるはず
- 巨大な中央機関不要はアジテーションとしても、仲介手数料モデルの破壊はあるはず

### ブロックチェーン
- bitcoin
  + P2Pネットワーク上の分散型台帳
  + 国境不在・世界単一市場。決済コストも安い。
  + ネットワーク内で合意が取れた段階で取引が確定する（リアルタイムではない）
  + 不特定多数のP2Pネットワーク（悪い人もたくさんいるはず）、P2Pノードには何の得がある？、一貫性を維持できる？、改善の心配は？
- ブロックチェーン
  + bitcoinはブロックチェーンを利用したアプリケーション
  + P2Pノードに同一の記録を同期
  + 一定のルールで正当性を決定、整合性を担保
  + P2Pノード：マイナー
  + パブリックなもの（bitcoin）とプライベートなもの（閉じたパートナーの中で）がある
- 一定分の取引の集まり⇒ブロック
- 複数ノードで並行に処理した結果を、他ノードが検証。不正な結果を排除する。マイナーはこれで報酬を得る。⇒インセンティブ設計が素晴らしかった
- 複数の正しい結果からただ一つの結果を採用する（コンセンサスアルゴリズムを決めておく）
- 権威者がいなくともグローバルに一意に整合性が取れる

### スマートコントラクト
- 自力で執行される契約処理（例：自動販売機）、概念は90年代に提唱
- データと契約処理をブロックチェーンに委ねる
  + データそのものも改ざんできない

### etherenum
- スマートコントラクト用のプロットフォーム、言語はSolidity
  + 値だけでなく、取引の状態遷移全体の記録台帳としてブロックチェーンを利用
  + 自由にコントラクトを作り独自データを扱える
  + clientからはjsonを投げる
- eherenum for Spring（ULFIRE）
  + etherenumへのアクセスを隠蔽、Spring Dataっぽく分散台帳にアクセス
  + @Etherenum、EtherenumCnfigudation
  + @TransactionListener
- コントラクト記述はとても難しい。ここが真の勝負。
- データサイズに応じたETHが発生する、データそのものは別管理（IPFS）でそこへのリンクを張る
- データは閲覧される可能性がある、シビアなデータはプライベートなストレージへ（個人情報、BtoBの取引先）


講演を聞いて、取引自体が偽物でないことをどう担保しているのか、とか、スパム的な取引をどう防いでいるのかが気になったけど、下記が分かりやすかった。
- [ブロックチェーンをもう一段深く理解する](http://wazanova.jp/items/1314)


## Spring CloudでDDD的なマイクロサービスを作ってみる

### 境界づけられたコンテキスト
- どこのチームもレガシーとの闘い、だんだん開発スピードが落ちてくる
  + レイヤー分けしていたり、コーディングルールもある
  + なのに数年経つとだんだん手を出せなくなってくる
  + データモデルがどんどん大きくなっていく
  + あちこちでデータを触っているのでどこがどこに影響を与えるか分からなくなる
- IFさえしっかりしておけば、中は自由にできる
  + 商品マスタなどはコピーして持っている
- 例：商品はあらゆるコンテキストに関わる（注文、出荷、請求、在庫、決済、カタログ、分析・・・）
  + 細かく切れば、それぞれのコンテキストから商品を触ることが重要
- DBを直接のぞけば、そのときの開発は早く進むが・・・

### ユビキタス言語
- チーム内の共通言語が英語なって気が付いたこと
  + 一生懸命話している単語が、会話／モデル／コードで共通の言葉になっている

### リポジトリ
- 「そのカラムに」「〇と□をjoin」
  + 業務とは関係ない、RepositoryがDomain Logicにはみ出していた
- Repositoryに隠蔽
- 結果として、Domain Logicが凝縮され、コードを読めばわりと業務が分かるようになった

### デモ：DDDスタイル
- 実践DDDは面白く、著者のコードも勉強になる
- 前は、ドメインモデルも、Entity構造、Enumで区分値などを知っていた⇒リポジトリに閉じ込めた
- 実践DDDでは、「集約がトランザクションの境界」を強調している
- ユビキタス言語をなるべくクラスにする（面倒くさいし、冗長な処理はあるけど）、例：OrderId
- repositoryの中で、DOMAのDaoを使っている
- Domain Serviceを定義するのは、集約と集約を取り扱うとき

### これから先に備えての素振り
- 集約同士の整合性を保つのにドメインイベント：Kafka
- クラスを知っていないとserialize / deseriaizeできない
  + jsonを使って、必要な項目だけを取ってくるようなUtilityを用意する
- CQRS
  + Domain Modelはなるべくputとgetだけにする
  + それぞれのアプリ用では、query用にViewModelを作る

### いつマイクロサービスする？
- チームが分かれるとき
  + DDDスタイルやイベントやり取りは、１つのアプリでもできる
  + 1つのアプリの方が、ブレークスルー的なモデルの変更に対応しやすい
- 将来的にマイクロサービスになっていけるアーキテクチャ（変化していけるアーキテクチャ）
  + 最初はDaoでもよい
  + 生き延びてドメインが分かってきたらDomain Model
  + 大きくなってきたらBCを分ける
  + チームが大きくなってきて分かれるときには、サービスを分ける
- 今回のデモ
  + 認証／userサービス／config-service／discovery-service
  + メインのアプリは最初は１つで作った
- State Sourcing ⇒ Event Sourcing


## ドメイン駆動設計とScala 〜既存プロジェクトへの適用〜
### Why DDD?
  + 常にドメインモデルを意識した設計をするので、行き過ぎた単純化・汎用化を防ぐことができる
  + Serviceに詰め込みすぎて肥大化するのを防ぐ
  + 各ドメインモデルの責務が明確になり、処理が散らばらない
  + 解決すべきは、技術的問題よりもビジネスの問題のこともある

### HRMOS採用管理での課題
- 巨大なモデルが存在（一つのclassでデータ持ちすぎ）
  + methodを持っていない
- ドメインモデル貧血症
  + XXService, XXUtilにビジネスロジックが散らばっている
  + ソフトウェアの関心事とビジネスの関心事が分離できていない

### モデルの再定義
- ユビキタス言語が適切に定義されているか？
  + 専門的すぎる用語は咀嚼して自分たちの言葉で再定義
  + チーム全員がその言葉を聞いて勘違いすることなく、同じ物事を思い浮かべることができるまで言葉を洗練する
  + 境界づけられたコンテキストの中で通じる言葉であればいい
  + 言葉の意味が変わらない範囲 = 境界づけられたコンテキスト
- モデルを明確に分けていなかった
  + requestを受け付けたモデル？ドメインモデル？response用のモデル？
  + package分けによるサポート
- clean architecture
  + controller
  + presenter
  + application/service：処理の振り分け＋トランザクション制御
  + domain：ドメインモデル
  + infrastructure/repository：永続化
  + gateway：外部サービスとのやり取り（ex. メールサービス）
  + util：ビジネスロジック以外のユーティリティ
- 見つけ出した言葉をドメインモデルに落とし込む

### Entity / ValueObject / Aggregate
- Entity：同一性を識別することが必要になるモデル
- ValueObject：イミュータブルに保つ値、状態を持たない（Scalaだとval / case class）
  + 誕生日：BirthDate型を用意して、calcAgeのようなメソッドを用意してやる
  + 同姓同名の人がいても別名なので人としては識別が必要、名前はただの文字列なのでValueObjectとして扱えばよい
  + 主体によって、Entity / ValueObjectは変化する
  + 千円札はValueObject、でも日本銀行からすれば識別が必要でお札はEntity
- Aggregate：Entityのライフサイクルを同一にするものを集める
  + トランザクション整合性を取る範囲、集約の外側は結果整合性
  + 自動車は、タイヤ・車両を含んだ集約のルートエンティティになる
  + 集約の内部のオブジェクトにアクセスしてよいのは集約のルートのみ、ルートを経由して制御すること
  + 加速する ⇒ 車に対して指示を出す ⇒ 車がタイヤやエンジンを制御する
  + モデルの一貫性を保つためのもの、そこに責任を負う範囲
- PlantUMLで書いてみた

### 集約が大きすぎる
- CQRS
  + すべてがドメインモデルだと重くなる
  + queryはドメインモデルをスキップ
- ドメインモデルとRepositoryの関係が悩ましい


## Payara Micro の設計と実装
http://www.slideshare.net/khasunuma/payara-microinternals

### Payara micro
- Embedded release of Payara
- Hazelcastによる自動クラスタリングがサポートされている
- Components
  + Embedded GlassFish
  + Hazelcast
  + Payara Service:監視サービス
    - Health check, notification, request tracking
- Core
  + fish.payara.micro
  + PayaraMicro(Bootstrapp) / PayaraMicroRuntime(Instance) / BootstrapException

### Startup
- javaコマンドでbootstrapのjarを呼ぶ（その時にoptionを付ける）
  + 多くの製品のshell scriptの中身はそうなっている
- メインクラス：PayaraMicro⇒Kernelを起動（jarファイル自身）⇒Payara Microが起動した状態

### Shutdown
- Ctrl + C => shutdown hookで埋め込みGlassFisをshutdown（もちろんAPIでも可能）

### 自動クラスタリング
- Hazelcastべったり
  + HazelcastはJCache providerでもある
- node立ち上げ
  + Hazelcastの初期設定（payara microのdefault or 独自）
  + Hazelcast instanceを起動 ⇒ caching providerを作成 ⇒ JNDIに登録
- Hazelcast clusterへの追加/削除は、自動的に実施される
- HTTP Auto-binding
  + Hazelcastが5900から探していくのを真似ている

### Application Deployment
- deploy方法
  + warを直接指定
  + ディレクトリを指定して、その中のwarをすべてdeploy
  + maven repository
  + 自分自身に埋め込まれているwarをdeploy（Uber jar）、META-INF/deploy
- GlassFish Deployerを使っており、EARなどもdeploy可能
- ROOT.warが、コンテキストルート"/"にdeployされる
  + それ以外のコンテキストルートの設定は、warファイルに依存する（deployment descriptorなど）
- maven repositoryから取るパターン、コンテキストルートはartifactIdが使われる

### Uber jar
- 実行可能jarの中にアプリケーションとruntimeが両方入っている、単体でwebアプリとして動かせる
- Spring Boot, WildFly swarmなど
- PayaraMicro#packageUberJar
  + 自分自身のファイルをすべてコピー
  + deploy対象のwarファイルを集めてすべてコピー
  + 設定を埋め込む
  + jarに書き出す

### Payara MicroのConfiguration
- hazelcast.xml
- domain.xml
  + GlassFishのdomain設定ファイル（config beanをjackson形式で書き出したもの、実行中に書き換えられる）
- Loggingはデフォルトではコンソール出力
  + -logToFileオプションで指定可能（ファイル出力する場合も、コンソールにも出力される）

### Payara Micro API
- Java EE7 Web Profile + α
- 設定＆オペレーション用のAPIを用意している、コマンドラインオプションをカバーしている

```java
PayaraMicro.getInstance().addDeployment("app.war").bootStrap();
```

- PayaraMicro.bootStrapの戻り値は、PayaraMicroRuntimeのinstanceを返す（以前はvoidだった）
- 設定はgetter/setter、ただしsetterは自分自身が戻り値なので、method chainで指定可能