#author("2020-07-01T09:24:38+00:00","","") #author("2020-07-01T09:25:16+00:00","","") [[SpringBoot]] * Spring Boot開発で使っている技術や名称 [#i3e71d71] Spring Boot特有の技術ではないが,Spring Bootを利用し開発する際によく使われる技術や概念など ** Gradle [#p3dacf76] - ビルドツールの1つで.jarとか.war(webサーバで動作する)を生成できる - 設定ファイルはjavaベースの記述が可能で,可読性や自由度は高い - mavenとの比較 -- mavenは設定ファイルを記述してコンパイル,gradleはjavaベースのスクリプトを書いてコンパイル --- gradleの方が記述の自由度が高く,コンパイルエラー文が行単位で出るのでミスが発見しやすい - mavenで出来ることをよりスマートにする ** アノテーション [#p11ef704] - 日本語では「注釈」という意味 - 「@hogehoge」と記述し,特定の機能を実装することができる -- @Overrideとか ** Lomboc [#haefb8f2] - Java特有の冗長なコード(getter,setter,toStringなど)を完結に書けるライブラリ - アノテーションを記述する -- フィールドの追加,変更をしても,getterなどを書き直す必要がない - 例 -- before public class Member { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Member [id=" + id + "]"; } } -- after import lombok.Data; @Data public class Member { private int id; } ** DI [#v6df0553] - [[https://qiita.com/park-jh/items/4df5c67d895b2ea219d6]]がよさそう?まとめる - Dependeny Injectionの略称,「オブジェクトの注入」と解釈する - 依存していることを外部で定義し,依存関係を使えるようにする -- 依存:メソッド内で別クラスのインスタンスを持つ public static void main(String[] args){ MessageBean bean = new MessageBean();//メソッド内でnewしてる } -- 関連:あるクラスの属性に別のクラスが存在する public class HelloApp { MessageBean bean; public HelloApp(){ this.bean = new MessageBean();//フィールドでnewしてる } } -- 依存は関連より弱い関係 - あるべき実装 public class HelloApp { MessageBean bean; public HelloApp(Message bean){ this.bean = bean; //newする際に,外からbeanを渡す=外から依存を注入する(DI) } } - interfaceを使ったクラス設計も,依存性か解決の手法の1つ public interface MessageBean { public void sayHello(String name);//抽象メソッドを定義 } - public class MessageBeanJa implements MessageBean { public void sayHello(String name){//抽象メソッドを実装する System.out.println("こんにちは、" + name); } } - 依存性が高いと? -- クラスBが完成していないと,クラスAが使えない -- 単体テスト(クラス単位でのテスト)を行うことができないため,バグの元を探すのが難しい -- 元のクラスBを変更するとクラスAも変更が必要 - メリット -- 依存関係をクラス外で定義することで,その依存性をなくすことができる -- クラスからnew演算子を消せる --- メモリ関連で良い,らしい -- シングルトン,プロトタイプ(呼び出されるごとに生成),セッションごとに生成などの制御も可能 - 使い方 -- フィールド変数(注入先の変数)の前に@Autowiredをつける -- @Component(または@Controller, @Service, @Repositoryなど)が付いているクラスから,クラスを探してnewとしてインスタンスを突っ込んでくれる @Service //抽象化したいクラスに付けるとDIオブジェクトとして管理される public class ProductService { (略) } -- public class ProductController { @Autowired //フィールドの前に付ける private ProductService productService;//勝手にnewして入れてくれる (productServiceを使ったメソッドなど) } ** DIコンテナ [#a010aaab] - DIを実現するためのフレームワーク - https://qiita.com/hinom77/items/1d7a30ba5444454a21a8 - DIオブジェクト(コンポーネント)の集合 -- ApplicationContextインターフェースを通じて,DIコンテナの登録されたコンポーネント(Bean)を取得する ** Bean [#k689c09c] - DIコンテナに登録するコンポーネントのことをSpringではBeanって言う -- https://dev.classmethod.jp/articles/springboot-what-is-bean/ - 理解としては以下の通り @Beanと書いたメソッドでインスタンス化されたクラスがシングルトンクラスとしてDIコンテナに登録される。 任意のクラスで@Autowiredで注入してアクセスできる。 - Beanはメソッドをどこでも使えるように,DI(@Component,@Serviceなど)はクラスをどこでも使えるようにという使い分けかな... - 使い方 - @Configurationと記述したクラス内のメソッドに@Beanを記述することで@Beanを定義する - 任意のフィールドに対して@AutoWiredを記述することで,そのBeanを利用できる - 元となるクラス public class Counter { private int count; public int getCount(){ return count++; } } - Beanを定義するクラス @Configuration //Bean用の設定 public class CreateCounter { @Bean //Beanを定義 public Counter getCounter(){ return new Counter();//シングルトンなCounterクラスが生成される } } - Beanを利用するクラス public class Process{ @Autowired//これを付与すると,コンストラクタを省略してDIコンテナから取得する Counter counter; public void printCounts(){ System.out.println(counter.getCount()); } } - 平山さんより情報 -- SpringBootでは,上で挙げた@Component系(@Component, @Controller, @Service, @Repositoryなど.@RestControllerとか@Controllerの仲間も)を付けたクラスに対して,内部的に自動的にBeanを作ったり,他のComponentの存在を元に@Autowiredしてくれる. - SpringBootでは,上で挙げた@Component系(@Component, @Controller, @Service, @Repositoryなど.@RestControllerとか@Controllerの仲間も)を付けたクラスに対して,内部的に自動的にBeanを作ったり,他のComponentの存在を元に@Autowiredしてくれる. @Service public class AccountService { private AccountRepository accountRepository; private PasswordEncoder passwordEncoder; public AccountService(AccountRepository accountRepository, PasswordEncoder passwordEncoder) { this.accountRepository = accountRepository;//別所で定義されたBeanを勝手に代入してくれる this.passwordEncoder = passwordEncoder; } } -- @Component系は各クラスが持つ機能とBeanが固く結びつくので,普遍的な処理をまとめたクラスを注入したいときはBeanで作る方がいい. --- AOP的な考え方 -- 外部クラスを注入したい場合など,そのクラスを直接いじってアノテーションを付けたりできない場合は,Beanでラップしてあげる. --- Pitcoinの例だとBCryptPasswordEncoderがそう.PasswordConfigurationというクラスでラップされてる.