スプリング#2(DI?)
(皆さんのフィードバック、悪評、善評を歓迎します)
スプリングが提供するDIについて議論する.
スプリングをつけて整理した感じなので、内容が不実で間違いがあるかもしれません.
これからも勉強を続けます
依存注入は、その依存性が既知である.たとえば、Serviceクラスでメンバークラスのオブジェクトを作成すると、このような状況が発生します.この場合、サービスクラスはメンバークラスに依存します.
Spring#1で説明したように、DIはオブジェクト向けの開発を支援するために使用されます.
DIはSRP,DIP,OCPを対象とする原則とする. SRP(単一責任原則)
SRP:クラスは1つの責任しか負いません.
上記のサービスクラスは、オブジェクトの作成にもサービスのみの機能にも使用できますので、SRPに違反します.オブジェクトの作成を他のクラスに委任して依存性を注入できる場合は、SRPを遵守できます. DIP(逆転依存の原則)
DIP:抽象に頼るには,具体化に頼ることはできない.(実装クラスに依存せず、インタフェースに依存することを示す)
継承メンバーのXxMemberオブジェクトを使用する必要がある場合は、コード OCP(オープン・クローズの原則)
OCP:ソフトウェア要素は拡張で開く必要がありますが、変更で閉じる必要があります.
サービスクラスがXxMemberではなくOoMemberオブジェクトを使用する必要がある場合は、サービスクラスを変更する必要があります.
DIの実現方法は大きく3つに分けられる. 純javaコード を使用
この部分は簡単に整理します.依存性を注入するには、個別のクラスが必要です. @Configurationとして構成されたクラスで@Beanを使用して を手動で登録します.
@Configurationとノイズを持つクラスはスプリングで情報を設定するクラスになります.メソッドに@beanを追加すると、返されたオブジェクトがスプリングコンテナに登録されます.スプリングコンテナに登録されているオブジェクトを
Spring bean @ をComponentScanで自動登録
@ComponentScanを使用して、@Componentを持つクラスをスプリングコンテナに自動的に登録します.
Mainクラスを実行すると、同じ結果が得られます.
ここでは、Lombokライブラリを適用してクラスに@RequiredArgsConstructorを追加すると、finalキーのあるフィールドが収集され、自動的にジェネレータが作成されます.(コードを簡略化し、オブジェクトを一定に保ち、アクセスをブロックできます.)
依存注入法は大体4種類ある.
1.注入作成者
2.注入修正者
3.現場注入
4.一般的な方法で注入
これまで、私たちがやってきたことは、作成者にどのように注入するかです.
様々な方法がありますが、「注入作成者」の方法を使用することができます.多くのDIフレームワークでは、この方法を推奨しています.
理由は.
漏れ
ほとんどの依存注入は、アプリケーションが閉じるまで変わらないでください.オブジェクトを作成するときに、コンストラクション関数注入を1回呼び出すだけで、private finalキーワードを使用して設計できます.
モディファイヤ注入メソッドではsetterメソッドをpublicに設定する必要があります.これにより、うっかり変更する人もいるかもしれませんが、変更すべきでないメソッドを開くのは良い設計方法ではありません.
また、作成者への注入時に依存注入が欠けている場合は、コンパイルエラーが発生します.修正者メソッドを使用している場合は、このメソッドが実行されますが、依存注入が発生した場合はNullPointExceptionが発生します.(コンパイルエラーは最大のエラーです!)
実はこの部分は自分で開発したのではなく、感じたのは、私が勉強した内容だけで、後で修正者注入などを使って、私はこの部分についての内容を追加します.
これは、設計時に常に「作成者注入」メソッドを使用し、オプションが必要な場合に「修正者」メソッドを使用することを意味します.(ということで…)
今まで私が理解していたDIはおかゆを整理して使っていてもぼんやりしていました足りない部分と間違った部分は後で修正します
スプリングが提供するDIについて議論する.
スプリングをつけて整理した感じなので、内容が不実で間違いがあるかもしれません.
これからも勉強を続けます
DIとは何ですか。
依存注入は、その依存性が既知である.たとえば、Serviceクラスでメンバークラスのオブジェクトを作成すると、このような状況が発生します.この場合、サービスクラスはメンバークラスに依存します.
import .Member;
pubic class Service() {
Member member = new Member();
...
}
外部クラスで直接サービスクラスからオブジェクトを作成するのではなく、メンバーオブジェクトを使用する場合はDIと呼ばれます.Spring#1で説明したように、DIはオブジェクト向けの開発を支援するために使用されます.
DIはSRP,DIP,OCPを対象とする原則とする.
SRP:クラスは1つの責任しか負いません.
DIP:抽象に頼るには,具体化に頼ることはできない.(実装クラスに依存せず、インタフェースに依存することを示す)
Member member = new XxxMember();
を記述し、DIPに違反します.外部クラスからXxxMemberへの依存性を得ることができれば,この問題も解決できる.public class Service{
Member member;
// 의존성 주입
logic(); // 어떠한 로직을 통해 member = new XxxMember를 기대할 수 있음
}
OCP:ソフトウェア要素は拡張で開く必要がありますが、変更で閉じる必要があります.
Member member = new XxxMember();
-> Member member = new OooMember();
依存性が外部クラスから注入される場合、必要に応じてXxMemberオブジェクトではなく、OCPに適合していることを確認できます.DIの実施方法
DIの実現方法は大きく3つに分けられる.
この部分は簡単に整理します.依存性を注入するには、個別のクラスが必要です.
// 객체를 생성하고 연결하는 설정 클래스
public class AppConfig {
public Service xxxMemberService() {
return new Service(new XxxMember);
}
}
その後、作成者を通じて依存性を注入します.public class Service{
Member member;
public Service(Member member) {
this.member = member
}
...
}
mainメソッドで実行します.public class Main {
public static void main(String[] args) {
AppConfig appConfig = new AppConfig();
Service service = appConfig.XxxMemberService();
...
}
}
粗末ですがSRP DIP OCPに合うコードを作りました@Configurationとノイズを持つクラスはスプリングで情報を設定するクラスになります.メソッドに@beanを追加すると、返されたオブジェクトがスプリングコンテナに登録されます.スプリングコンテナに登録されているオブジェクトを
스프링 빈
と呼びます.Springbinは@bean付きメソッドの名前をspringbinの名前として使用します.@Configuration
public class AppConfig {
@bean
public Service xxxMemberService() {
return new Service(new XxxMember);
}
}
Mainクラスのスプリングコンテナを変更します.スプリングシートを使用するには、AnnotationConfigApplicationContextを使用します.(スプリングを使用するとspringApplicationでmainメソッドが提供されるのでmainメソッドは使用しません.)public class Main {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
Service service = ac.getBean(Service.class);
...
}
AnnotationConfigApplicationContextのgetBeanメソッドを使用すると、Springコンテナに登録されているサービスオブジェクト(新しいXxxmember)が自動的に呼び出され、依存性が注入されます.Spring bean
@ComponentScanを使用して、@Componentを持つクラスをスプリングコンテナに自動的に登録します.
@Configuration
@ComponentScan
public class AppConfig {
}
サービスクラスに@コンポーネントを追加し、ジェネレータに@Autowiredを追加します.@Component
public class Service{
Member member;
@Autowired
public Service(Member member) {
this.member = member
}
...
}
ジェネレータに@Autowiredを指定すると、スプリングはコンテナタイプと同じ空を自動的に検索して注入します.(getBean(Services.class)と同様)Mainクラスを実行すると、同じ結果が得られます.
ここでは、Lombokライブラリを適用してクラスに@RequiredArgsConstructorを追加すると、finalキーのあるフィールドが収集され、自動的にジェネレータが作成されます.(コードを簡略化し、オブジェクトを一定に保ち、アクセスをブロックできます.)
최종코드
@Component
@RequiredArgsConstructor
public class Service{
private final Member member;
...
}
依存性注入方法依存注入法は大体4種類ある.
1.注入作成者
2.注入修正者
3.現場注入
4.一般的な方法で注入
これまで、私たちがやってきたことは、作成者にどのように注入するかです.
様々な方法がありますが、「注入作成者」の方法を使用することができます.多くのDIフレームワークでは、この方法を推奨しています.
理由は.
漏れ
ほとんどの依存注入は、アプリケーションが閉じるまで変わらないでください.オブジェクトを作成するときに、コンストラクション関数注入を1回呼び出すだけで、private finalキーワードを使用して設計できます.
モディファイヤ注入メソッドではsetterメソッドをpublicに設定する必要があります.これにより、うっかり変更する人もいるかもしれませんが、変更すべきでないメソッドを開くのは良い設計方法ではありません.
また、作成者への注入時に依存注入が欠けている場合は、コンパイルエラーが発生します.修正者メソッドを使用している場合は、このメソッドが実行されますが、依存注入が発生した場合はNullPointExceptionが発生します.(コンパイルエラーは最大のエラーです!)
実はこの部分は自分で開発したのではなく、感じたのは、私が勉強した内容だけで、後で修正者注入などを使って、私はこの部分についての内容を追加します.
これは、設計時に常に「作成者注入」メソッドを使用し、オプションが必要な場合に「修正者」メソッドを使用することを意味します.(ということで…)
今まで私が理解していたDIはおかゆを整理して使っていてもぼんやりしていました足りない部分と間違った部分は後で修正します
Reference
この問題について(スプリング#2(DI?)), 我々は、より多くの情報をここで見つけました https://velog.io/@gudwn357/spring2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol