メモ : 2016年に省力的にpure java (w lombok)でアプリを書く一方策

#  何をしたい？

- 自分向け: 会員制アプリ**"(仮)ルターのリンゴ"** 開発メモ #随時更新
- 一般化 : コツコツと小さくはじめて,なるべくその後も使えるように。

## やりたいこと

- 週末作業中心でwebアプリをお勉強&試作から商用までひとりでやりきる(スケジュールはタイトではない)。
- スケーラビリティやセキュリティ対策も商用までもっていく。
- 仕事でjava書いているので,週末作業もなるべくjavaで。ボイラープレートは嫌いだが。

## 方針 : 

- ベンダーの便利なものは使いつつ,ベンダー囲い込みはなるべく排除。
- 基本,オープンソースを活用

## 一方策としてのGoogelCloudPlatform
 *※　どれか一つに決め打った方が調査が楽という意味で,今回はGCP(GoogelCloudPlatform)決め打ち*

- GCE上のLinux(たぶんubuntu)上でアプリ開発。GCPのために覚えること :管理用のgcloudコマンド等
- RDBは無難にMySQLを使用(メンテナンスは基本GCPに任せる。)。GCPのために覚えること :Google Cloud SQLインスタンスの作り方等

- WAFは,守備範囲が広そうなspringbootを採用。RESTでインターフェース開発を中心に進める。

##　将来を見据えての話。
- グラフデータベースが必要となった場合にはNeo4j。内部コードとの関係でscalaも併用。
- アプリが遅いとかなった時にはフロントエンドをGo(on GAE)に置き換えてつく(スケールアウトが早いとうのメリット)
- Kotlinはいつでも併用可としておく。


# springboot on lombokメモ(仮)
## 使いはじめは簡単
 理由 : [はじめてのSpring Boot](http://j.mp/haji_sb)（[サポートページ](https://github.com/making/hajiboot-samples)）もlombokを使っているため。

###エンティティ記述の例
詳しくは,[こちら](http://mmts1007.hatenablog.jp/entry/2015/10/15/204400)を参考に。

```java
import javax.persistence.*;
import lombok.*;

@Data
@Entity
@Table(name = "tasks")
@NoArgsConstructor
@AllArgsConstructor
public class Task {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false)
    private String context;
}
```
コンストラクタTask(...)やフィールドへのアクセッサはLombokにより,自動生成される。

## 主なlombokアノテーションは頭に入れておく。
  とりあえずimport lombok.*で使えるようになるlombokアノテーションをABC順に軽くまとめておく(ToDo:あとで一覧化)

### [@AllArgsConstructor](https://projectlombok.org/features/Constructor.html)
 すべてのフィールドを持つコンストラクタを生成
  ※　@NoArgsConstructor : 引数なしのコンストラクタを生成
    注　コンストラクタを記述していない場合, オブジェクト生成時にデフォルトコンストラクタが呼ばれ,デフォルト値(null等)に初期化される...というjava固有の問題を緩和。
　※@RequiredArgsConstructor   : (略)

### [@Builder](https://projectlombok.org/features/Builder.html)
  ビルダーパターンを簡単に生成するアノテーション。コンストラクタに多くの引数を渡さなければオブジェクトを作成できないときなどに活用。
　lombokサイトにある例(以下)のように書くことで,ビルダーの長ったらしい記述が一気に不要になる。

```java
@Builder
 public class Person {
   private String name;
   private int age;
   @Singular("list") private List<String> list;
}
```

オブジェクトの生成例:

```java
import lombok.val;
val p = Person.builder()
     .name("太郎").age(29)
     .list("hoge").list("fuga").list(Arrays.asList("fizz", "buzz");
```
※　追加メソッドとして自動生成したい場合は @Singular でフィールドをアノテート。

### [@Cleanup](https://projectlombok.org/features/Cleanup.html)　#非推奨
  変数に@Cleanupを付加 =>現在のスコープを抜けた際にクリーンアップするコードを生成。try-with-resourcesを使えば良いので非推奨。
  例　@Cleanup InputStream in = new FileInputStream(args[0]);
  ※　in.close()の記述が不要に。クリーンアップ処理はfinally内でnullチェックとともに実行。

#### @Java 7 以降では便利構文 try-with-resourcesを使えば良い。

```java 
public class Test implements AutoCloseable{ //javaクラスにAutoCloseable を導入
...
  try(  FileInputStream is2 = new FileInputStream("hoge.txt"); //Java6までめんどくさかったリソースのクローズを自動化
        FileOutputStream os2 = new FileOutputStream("hige.txt")
      ) {
      InputStreamReader ir2 = new InputStreamReader(is2,"Shift_JIS");
      OutputStreamWriter ow2 = new OutputStreamWriter(os2,"UTF-8");
      int tmp;
      while((tmp = ir2.read()) != -1){
                ow2.write(tmp);
      }
  } catch (Exception e){
      e.printStackTrace();
  }
  //  finally block を書くことはほとんどなし
  ...

}
```
要するに, implements AutoCloseableでfinally blockいらずに,という話。

###[@Data](https://projectlombok.org/features/Data.html)　#非推奨
: POJO や Beans に使用するアクセッサ系アノテーション。Setterが常に付加されてしまうため非推奨。
   @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor も自動で付与
　※フィールドに個別に@Getter/@Setterが付与された場合, Getter/Setterが優先。
  ※　@ToString : クラスのフィールド名、フィールドの値を出力するように toString メソッドをオーバーライド(デバッグ目的)
    


###[@EqualsAndHashCode](https://projectlombok.org/features/EqualsAndHashCode.html)
  オブジェクトに定義されているフィールドの値で equails, hashCode を算出できるように equails, hashCode メソッドをオーバーライド
  #理解が不十分なので後で追加調査..
### @Setter (+@NonNull) 

```java
@Setter @NonNull
private List<Person> members;
```
　@NonNullアノテーションが、Lombokが生成するsetter対応フィールドに付与されているとき、null値をNullPointerExceptionにするnullチェック付きのsetterコードが生成される（以下みたいなの）。

```java
public void setMembers(@NonNull final List<Person> members) {
    if (members == null) throw new java.lang.NullPointerException("members");
    this.members = members;
}
```


###[@Value](https://projectlombok.org/features/Value.html)
  : イミュータブル(不変の値)なクラスを生成するアノテーション
  値の変更ができないため、フィールドはデフォルトで private, final に。setter は生成されない。

#### (付記) ドメイン駆動設計(DDD)の不変デザインパターンVO（Value Objects）
  インスタンスコンストラクタでプロパティを初期化し,プロパティの変更（set）は外から出来ないようにするクラス。Immutableなオブジェクトが生成される。
cf.http://masuda220.jugem.jp/?eid=308

## 関連リンク
###続きのお勉強先:
http://qiita.com/opengl-8080/items/671ffd4bf84fe5e32557

### ありえるの方がLombokに関する  利用ルールを下書きしてくれている。
https://gist.github.com/asufana/b4bb11ab1235b8fe7ca1

### Project Lombok によるカスタム AST 変換
http://www.ibm.com/developerworks/jp/java/library/j-lombok/

> Lombok は AST (Abstract Syntax Tree: 抽象構文木) の構造をコンパイル時に変更することによって、AST の変換を行います。AST は、コンパイラーによって作成される構文解析後のソース・コードのツリー表現であり、XML ファイルの DOM ツリー・モデルに似ています。Lombok はこの AST を変更 (つまり変換) するという方法でソース・コードを簡潔に維持するため、プレーン・テキストのコード生成とは違ってコードが膨れ上がることがありません。Lombok が生成するコードは、CGLib や ASM などのライブラリーで直接バイト・コードを操作する場合とは異なり、同じコンパイル単位に含まれるクラスにも可視になります。