【Java】Spring Boot 基本からHello Worldまで

#Springとは
Java開発におけるフレームワーク(=効率化tool)
ex：DBにアクセスするクラスなど

###Springの全体図
![spring.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/25851496-afb4-b1de-be10-3c718333c3dc.png)

##SpringBoot（≒スプリングフレームワーク）
* Springフレームワークがベース(もともとJavaのフレームワーク)
* 複数のライブラリの集合体。ビジネス系のApp作るために必要なものを網羅している
    * Spring MVC
    * Spring JDBC
    * Spring Security
    * Spring Data (JPA)
* 複数のフレームワークを使用する際に設定をXMLでゴリゴリ書かなくても簡単に設定できるのがSpring Boot

##Spring DI 
* DI ：Dependency Injection(依存性の注入)
* Spring DI =DIコンテナのこと
* インスタンスの管理を行う
* Springコア部分の機能を担う。Soring MVCなどはこの機能に沿っている。

####Dependency Injectionとは
* newという演算子でobject生成する方法

``` Java
//Dateオブジェクトのインスタンスをtodayに代入
var today = new Date();
var day = today.getDate();
console.log("今日は"+ day +"日です");
```

* これに対してDIではインスタンス変数（注入先の変数）に@Autowired(アノテーション)を付与
@Componentアノテーションのついたクラスの中から該当するクラスに対してオブジェクトを生成しインジェクトしてくれる(newしてインスタンスを突っ込んでくれる)

```Java
@Controller
public class ProductController {
    @Autowired
    private ProductService productService;
   //略
}
```
* 良いソフトウェアコードの考え方に沿っている
    * **高凝集性(High Cohesion)**：責任範囲が明確
    * **疎結合性(Low Coupling)**：お互いに依存していない
* new演算子を用いると密結合になってしまうが、
コンテナ(=第三者)にインジェクトしてもらうことで疎結合にすることができる！👏

#SpringBootでHello Worldを表示まで(IntelliJ + gradleを使用)
###設定
* Spring Initializr でProject SDKを指定(Java11)
* ビルドシステム→Gradleを選択
* Language→Javaを選択
* Package→Jarを選択<br>
圧縮したままの状態で、Javaの実行環境で動かすことができる
* Template Engines→Thymeleaf
* Web→Spring Web<br>
どこのURLにエンドポイント持たせるかを適切にハンドリングしてくれる![dependencies.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/d8eb813b-5c63-d8bc-e990-a94403eb1747.png)



###フォルダ構成
* `build.gradle`：グレードルのプロジェクトであることがわかる
    * group：成果物であるjarファイルの名前
    * source compatibility：Java11以降の環境で動く
    * dependencies ；使いたいライブラリを記述。ここに書くとリポジトリから勝手にとってきてくれる！👏
        * **ソースコードがコンパクトに！**
        * repository指定場所が違う/プロキシが違うとかでダウンロードできないトラブルもあるので注意

* `src/main/java` ：配下にjavaのコード書くという決まり
* `src/main/resources/applications.propaties`：ポートを簡単に変更できる

```java
server.port=8081
```

###クラス作成
* `src/main/java/com.example.demo`上で、右クリック > New > Class 
* Name: SampleController

![demo1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/11079ea4-0e89-7e2b-b3b7-a5704221b4a6.png)

```Java
//Springbootを動かす時に、URLを受け取り、index.htmlを返す
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class SampleController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model) {
        model.addAttribute("message", "Hello World!!");
        return "index";
    }
}
```

###HTMLファイル作成
* `main/resources/templates` > New > HTML File
* Name: `index.html`


![HTML.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/5f9ff87c-4048-9fd2-f305-56f11cb5ff06.png)

```html:index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello World</title>
    <meta charset="utf-8" />
</head>
<body>
<h1>SpringBoot</h1>
<p>
    <span th:text="${message}"></span>
</p>
</body>
</html>
```
###起動して完了！
* main関数のエントリポイントとなる関数を選んでrunすると実行される
* 右クリック > Run > DemoApplication
* tomcatが勝手に動いて8080でportが開く
* http://localhost:8080/ にアクセス
![結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/4877ba0b-c45d-6fb9-a415-8a686e5ddd36.png)

##(注)Portについて
* Webアプリケーションでは8080ではなくhttps(=port443)を使用している
* この仕組みはALB(アプリケーションロードバランサ)を使って実現
    * ALBでSSLTLS暗号化の処理をする
    * SSLオフロード(終端)で暗号化を解く
    * 後ろにある中で動いているVMやEC２を8080で受ける
* 外からは8080って入れないけど中で動いているのは8080ということ
![spring3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/01fa4222-7e26-da3f-4dd9-6b81503626bd.png)