(Spring) DI, IoC, SOLID

Spring

05/21/2021







๐Ÿš€ DI (Dependency Injection)

: ์˜์กด์„ฑ ์ฃผ์ž…

A๋ผ๋Š” ํฌ๋ž˜์Šค์—์„œ B๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ A๋Š” B์˜ ์˜์กด์„ฑ์„ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•œ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์„ค๊ณ„๋ฅผ ํ•  ๋•Œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์ด ํ–ฅ์ƒ๋œ๋‹ค. ๊ฐ์ฒด๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง€๋ฉด์„œ ์œ ์—ฐํ•œ ์ฝ”๋“œ ์ž‘์„ฑ ๊ฐ€๋Šฅ.




๐Ÿš€ IoC (Inversion of Control)

์ œ์–ด์˜ ๋ฐ˜์ „์ด๋ผ๋Š” ๋œป.

๊ทผ๋ฐ why ์ œ์–ด์˜ ๋ฐ˜์ „?

๊ธฐ์กด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ๋…ผ๋ฆฌ ํ๋ฆ„์€, Aํด๋ž˜์Šค์—์„œ Bํด๋ž˜์Šค๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด, Aํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ ๋‹ค์Œ์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” Bํด๋ž˜์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ IoC ์˜ ํ”„๋กœ์„ธ์Šค์—์„œ๋Š” ์ฃผ์ž… ๊ฐ์ฒด๋กœ ์ •์˜๋˜์–ด์žˆ๋Š” ํด๋ž˜์Šค๋“ค(Bํด๋ž˜์Šค)์„ ๋จผ์ € ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ๋‹ค์Œ์— ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์ธ ํด๋ž˜์Šค(Aํด๋ž˜์Šค)๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ œ์–ด์˜ ๋ฐ˜์ „ ๋˜๋Š” ์—ญํ–‰์ด๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” IoC Container : ๋นˆ(bean)์„ ๋งŒ๋“ค๊ณ  ์˜์กด์„ฑ์„ ์—ฎ์–ด์ฃผ๋Š” ์ผ์„ ํ•œ๋‹ค.


ํŠน์ •ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†ํ•˜๊ฑฐ๋‚˜ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ํŠน์ • ์–ด๋…ธํ…Œ์ด์…˜์ด ์ •์˜๋˜์–ด์žˆ๊ฑฐ๋‚˜(ex. @Controller), ์•„๋‹ˆ๋ฉด ๋นˆ์œผ๋กœ ์ง์ ‘ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜์˜ ๊ฒฝ์šฐ์—๋งŒ ์Šคํ”„๋ง IoC ์ปจํ…Œ์ด๋„ˆ์— ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ ๊ฐ์ฒด๋“ค์€ IoC์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์˜์กด์„ฑ์œผ๋กœ ์—ฎ์–ด์ค€๋‹ค. (๊ธฐ๋ณธ์ ์œผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…์€ IoC์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ ๊ฐ์ฒด๋“ค๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. )




๐Ÿ”Œ Spring ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ• 3๊ฐ€์ง€


  • ์ƒ์„ฑ์ž ์ฃผ์ž…
  • ์„ธํ„ฐ ์ฃผ์ž…
  • ํ•„๋“œ ์ฃผ์ž…


๋จผ์ € DI์˜ ์˜์กด์„ฑ ์ฃผ์ž…์€ Setter ์ฃผ์ž…, ์ƒ์„ฑ์ž ์ฃผ์ž… ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

โœ๏ธ setter ์ฃผ์ž…

JAVA
public class Library {
private Novel novel;
public cvoid setNovel(Novel novel){
this.novel = novel
}
public void readNovel(){
novel.subject();
}
}
JAVA
public interface novel{
void subject();
}
JAVA
public class NovelImple implements Novel {
@Override
public void subject() {
System.out.println("This Subject is Comics");
}
}
JAVA
public class Main {
public static void main(String[] args) {
Library library = new Library();
//1.
library.setNevel(new NovelImple());
//2.
library.setNovel(new Novel(){
@Override
public void subject(){
System.out.println("This Subject is Romans");
}
});
// ๊ตฌํ˜„์ฒด ์ฃผ์ž… ํ›„ ํ˜ธ์ถœ
library.readNovel();
}
}
  • setter ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌํ˜„์ฒด์˜ ๋‚ด๋ถ€ ๋™์ž‘์„ ์•Œ์ง€ ๋ชปํ•˜๊ณ  ์•Œ ํ•„์š”๋„ ์—†๊ฒŒ ๋œ๋‹ค.
  • Library ํด๋ž˜์Šค์˜ readNovel() ๋ฉ”์„œ๋“œ๋Š” Novel ํƒ€์ž…์˜ ๊ฐ์ฒด์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค. But, setter์— ์ฃผ์ž…์ด ํ•„์š”ํ•œ ๊ฐ์ฒด๊ฐ€ ์ฃผ์ž…๋˜์ง€ ์•Š์•„๋„ ๊ฐ์ฒด๋Š” ์–ผ๋งˆ๋“ ์ง€ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด์„ฑ ์ฃผ์ž… ์—†์ด readNovel() ๋ฉ”์†Œ๋“œ์— ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด NullPointerExceoption ์ด ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ๏ธ ์ƒ์„ฑ์ž ์ฃผ์ž…

์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด Library ํด๋ž˜์Šค์˜ setter๋ฅผ ์—†์• ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑ์ž๋กœ ์ฃผ์ž…์„ ํ•˜๊ฒŒ๋œ๋‹ค.

JAVA
public class Library {
private Novel novel;
public Library(Novel novel){
this.novel = novel;
}
public void readNovel(){
novel.subject();
}
}
  • ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜์ง€ ์•Š์„ ์‹œ์—” Library ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— NullPointException์ด ๋ฐœ์ƒํ•  ์ผ์ด ์—†๋‹ค. ์ปดํŒŒ์ผ ํƒ€์ž„์— ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ผ ์ˆ˜ ์žˆ์Œ.


Spring์˜ ์˜์กด์„ฑ์ฃผ์ž…์€ ์œ„์˜ ๋‘๊ฐ€์ง€์™€ ๋”ํ•ด์„œ ํ•„๋“œ์ฃผ์ž…๊นŒ์ง€ ์„ธ ๊ฐ€์ง€์˜ ๋ฐฉ๋ฒ•์ด ์žˆ์Œ.


โœ๏ธ ํ•„๋“œ ์ฃผ์ž…

JAVA
public class A implements B {
@Autowired
private B b ;
@Override
public void testMethod(){
b.bMethod();
}
}

ํ•„๋“œ ์ฃผ์ž…์‹œ ๋‹จ์ 

: ์ˆœํ™˜์ฐธ์กฐ์‹œ StackOverflowError ๋ฐœ์ƒ์‹œํ‚ด <- ์ด๋Š” ๊ฐ์ฒด๊ฐ€ ๋ชจ๋‘ ์ƒ์„ฑ์ด ๋œ ํ›„ ๋กœ์ง์ƒ์—์„œ ์ˆœํ™˜์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ์ง์ด ๊ตฌ๋™๋˜๊ธฐ ์ „ ๊นŒ์ง€ ์ˆœํ™˜์ฐธ์กฐ์ธ์ง€ ๋ชจ๋ฅธ๋‹ค.

but ์ƒ์„ฑ์ž ์ฃผ์ž…์œผ๋กœ ์ด๋ฃจ์—ฌ์งˆ ๊ฒฝ์šฐ, ๋นˆ ์ƒ์„ฑ ์‹œ ๊ฐ์ฒด๊ฐ„ ์ˆœํ™˜์ฐธ์กฐ๋ฅผ ํ•˜๊ณ ์žˆ๋Š” ๊ฒฝ์šฐ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๋ฉ”์„ธ์ง€์™€ ํ•จ๊ป˜ ์Šคํ”„๋ง ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ๋™๋˜์ง€ ์•Š๋Š”๋‹ค.

Description : The dependencies of some of the beans in the application context form a cycle


why? Aclass์™€ Bclass๊ฐ€ ์„œ๋กœ ์ˆœํ™˜์ฐธ์กฐ ํ•˜๊ณ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ใ„นํ•  ๊ฒฝ์šฐ์—, ์ƒ์„ฑ์ž ์ฃผ์ž…์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋กœ์ง์ด ์ˆ˜ํ–‰๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

new Aclass(new Bclass(new Aclass(new ... )))

-> ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋นˆ์„ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ์—์„œ ๊ฐ์ฒด์ƒ์„ฑ์— ์‚ฌ์ดํด ๊ด€๊ณ„๊ฐ€ ์ƒ๊ธด๋‹ค.



Intro to Inversion of Control and Dependency Injection with Spring

์Šคํ”„๋ง - ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ , ํ•„๋“œ์ธ์ ์…˜์ด ์ข‹์ง€ ์•Š์€ ์ด์œ 

Spring โ€“ ์ œ์–ด ๋ฐ˜์ „ vs ์ข…์†์„ฑ ์ฃผ์ž…





๐Ÿš€ SOLID


SOLID๋ž€? ํด๋ฆฐ์ฝ”๋“œ๋กœ ์œ ๋ช…ํ•œ ๋กœ๋ฒ„ํŠธ ๋งˆํ‹ด์ด ์ข‹์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์˜ 5๊ฐ€์ง€ ์›์น™(SRP, OCP, LSP, ISP, DIP)์˜ ์•ž ๊ธ€์ž๋ฅผ ๋”ฐ์„œ ๋งŒ๋“  ์šฉ์–ด


SRP(Single Responsibility Principle) ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™

: ๊ฐ์ฒด๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด๊ฐ„์˜ ์‘์ง‘๋„๋Š” ๋†’์œผ๋ฉฐ ๊ฒฐํ•ฉ๋„๋Š” ๋‚ฎ์€ ํ”„๋กœ๊ทธ๋žจ์„ ์„ค๊ณ„ํ•˜๊ธฐ ์œ„ํ•œ ์›์น™. ํ•œ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฃจ๋Š” ๊ธฐ๋Šฅ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์‘์ง‘๋„๊ฐ€ ๋‚ฎ์•„์ง€๊ณ  ๋ฉ”์†Œ๋“œ๊ฐ„์˜ ๊ฒฐํ•ฉ์ด ๊ฐ•ํ•ด์งˆ ์ˆ˜๋ฐ–์— ์—†๋‹ค.


OCP(Open/Clodes Principle) ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™

: ๋‹คํ˜•์„ฑ์„ ํ†ตํ•œ ๊ธฐ๋Šฅ์˜ ํ™•์žฅ. ์ž์‹ ์˜ ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ์–ด์•ผ ํ•˜๊ณ  ์ฃผ๋ณ€์— ๋ณ€ํ™”์—์„œ๋Š” ๋‹ซํ˜€์žˆ์–ด์•ผ ํ•œ๋‹ค.

๊ฐœ๋ฐฉ ํ์‡„ ์›์น™(OCP) ์˜ˆ์‹œ


LSP(Liskov Substitution Principle) ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™

: ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” ์ž์‹ ํด๋ž˜์Šค๋“ค์€ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๊ทœ์•ฝ์„ ์ง€์ณ์•ผ ํ•œ๋‹ค.


ISP(Interface Segregation Principle) ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™

: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž์‹ ์ด ์ด์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”์„œ๋“œ์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค๋Š” ์›์น™. ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด ๋‹ค์ค‘์ƒ์†์„ ์ด๋ฃฌ๋‹ค.


DIP(Dependency Inversion Principle) ์˜์กด๊ด€๊ณ„ ์—ญ์ „ ์›์น™

: ๊ตฌํ˜„์ฒด๋ณด๋‹ค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ถ”์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•ด์•ผ ์œ ์—ฐํ•˜๊ฒŒ ๊ตฌํ˜„์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.





SOLID (SRP, OCP, LSP, ISP, DIP)


WRITTEN BY

Keep It Simple, Stupid